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

Make iTime an optional uniform #2015

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
2 changes: 1 addition & 1 deletion crates/figma_import/src/shader_schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ pub struct ShaderUniformJson {
impl Into<(String, ShaderUniform)> for ShaderUniformJson {
fn into(self) -> (String, ShaderUniform) {
let uniform_value = match self.uniform_type.as_str() {
"float" => {
"float" | "iTime" => {
if let Some(float_val) = self.uniform_value.as_f64() {
Some(ShaderUniformValue { value_type: Some(FloatValue(float_val as f32)) })
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -669,7 +669,7 @@ fun ShaderUniform.applyToShader(
val definedType = shaderUniformMap[name]?.type
when (value.valueTypeCase) {
ValueTypeCase.FLOAT_VALUE -> {
if (definedType == "float") {
if (definedType == "float" || definedType == "iTime") {
shader.setFloatUniform(name, value.floatValue)
}
}
Expand Down Expand Up @@ -755,15 +755,6 @@ internal fun getCustomBrush(
v.applyToShader(shader, it.shaderUniformsMap)
}
customizations.getShaderUniformList(nodeName)?.forEach { customUniform ->
// iTime is preset uniform which is not in the shader uniforms map.
// We need a customization for it when the shader code animate over time.
if (customUniform.name == ShaderHelper.UNIFORM_TIME) {
shader.setFloatUniform(
customUniform.name,
customUniform.value.floatValue,
)
return@forEach
}
if (it.shaderUniformsMap.containsKey(customUniform.name)) {
customUniform.applyToShader(shader, it.shaderUniformsMap)
} else {
Expand All @@ -773,15 +764,6 @@ internal fun getCustomBrush(
customizations.getShaderUniformStateList(nodeName)?.forEach { customUniformState
->
val customUniform = customUniformState.value
// iTime is preset uniform which is not in the shader uniforms map.
// We need a customization for it when the shader code animate over time.
if (customUniform.name == ShaderHelper.UNIFORM_TIME) {
shader.setFloatUniform(
customUniform.name,
customUniform.value.floatValue,
)
return@forEach
}
if (it.shaderUniformsMap.containsKey(customUniform.name)) {
customUniform.applyToShader(shader, it.shaderUniformsMap)
} else {
Expand Down
Binary file not shown.
73 changes: 47 additions & 26 deletions support-figma/extended-layout-plugin/src/shader.html
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@
<div style="border: 2px black solid;">
<div>
<div style="height: 32px;" class="center-vertically-container">uniform float3 iResolution;</div>
<div style="border-top: 1px black solid; height: 32px;" class="center-vertically-container">uniform
float iTime;</div>
</div>
<div id="uniforms"></div>
</div>
Expand All @@ -44,12 +42,12 @@
</div>
</div>
<div style="display:flex; flex-wrap: wrap; overflow-y: auto; gap: 4px; margin-top: 8px;">
<button class="button--primary" onclick="loadShaderCode('julia')">Julia</button>
<button class="button--primary" onclick="loadShaderCode('cloudy_sky')">CloudySky</button>
<button class="button--primary" onclick="loadShaderCode('discrete_ocean')">DiscreteOcean</button>
<button class="button--primary" onclick="loadShaderCode('fibonacci_sphere')">FibonacciSphere</button>
<button class="button--primary" onclick="loadShaderCode('gradient')">Gradient</button>
<button class="button--primary" onclick="loadShaderCode('star')">Star</button>
<button class="button--primary" onclick="loadPresetShaderCode('julia')">Julia</button>
<button class="button--primary" onclick="loadPresetShaderCode('cloudy_sky')">CloudySky</button>
<button class="button--primary" onclick="loadPresetShaderCode('discrete_ocean')">DiscreteOcean</button>
<button class="button--primary" onclick="loadPresetShaderCode('fibonacci_sphere')">FibonacciSphere</button>
<button class="button--primary" onclick="loadPresetShaderCode('gradient')">Gradient</button>
<button class="button--primary" onclick="loadPresetShaderCode('star')">Star</button>
<button class="button--primary" onclick="clearShaderCode()">CUSTOM</button>
</div>

Expand Down Expand Up @@ -109,7 +107,9 @@
<dialog id="createUniformDialog">
<div><b>Choose which uniform to create</b></div>
<p>
<label><input type="radio" name="uniformType" value="float" checked="true">Float</label>
<label><input type="radio" name="uniformType" value="iTime" checked="true">iTime</label>
<br>
<label><input type="radio" name="uniformType" value="float">Float</label>
<br>
<label><input type="radio" name="uniformType" value="floatArray">Float Array</label>
<br>
Expand Down Expand Up @@ -197,8 +197,9 @@
<!-- END OF SHADER PLUGIN UI -->

<script>
let presetUniforms = ["iResolution", "iMouse", "iTime"];
let presetUniforms = ["iResolution", "iMouse"];
let shaderUniformTypeMap = {
"iTime": "float",
"color3": "float3",
"color4": "float4",
};
Expand Down Expand Up @@ -239,7 +240,7 @@
createUniformDialog.showModal();
}

function continueUniformCreation() {
async function continueUniformCreation() {
let selectedUniformType = document.querySelector('input[name="uniformType"]:checked');
if (selectedUniformType) {
switch (selectedUniformType.value) {
Expand All @@ -255,6 +256,10 @@
case "int":
createIntUniformDialog.showModal();
break;
case "iTime":
createShaderTimeUniform();
await runShader();
break;
}
createUniformDialog.close();
} else {
Expand Down Expand Up @@ -446,6 +451,14 @@
createIntUniformDialog.close();
};

function createShaderTimeUniform() {
const newUniformEntry = createShaderUniform("iTime", "iTime");
if (!newUniformEntry) {
return;
}
uniforms.appendChild(newUniformEntry);
}

function createShaderUniform(uniformName, uniformType) {
if (presetUniforms.includes(uniformName) || customUniforms.includes(uniformName)) {
alert("This uniform already exists, please use a different name.");
Expand Down Expand Up @@ -523,6 +536,7 @@
function previewUniformValue(uniform) {
const type = uniformTypeMap.get(uniform);
const floatArray = [];
// iTime is handled separately when the uniforms push the iTime value.
switch (type) {
case "float":
const slider = document.getElementById(`slider_${uniform}`);
Expand Down Expand Up @@ -576,6 +590,9 @@
b: rgb3.b,
a: alpha ? parseFloat(alpha.value) : 1.0
};
case "iTime":
// DesignCompose should simulate the time change.
return 0;
}
}

Expand Down Expand Up @@ -609,8 +626,8 @@
await runShader();
}

function loadShaderCode(shader) {
clearUniforms();
function loadPresetShaderCode(shader) {
// The shader code will run when it receives a 'shaderCode' message.
parent.postMessage({
pluginMessage: {
msg: 'loadShaderCode',
Expand All @@ -636,18 +653,14 @@
let extraUniforms = "////// User supplied inputs ////// \n";
customUniforms.forEach(function (uniform) {
const type = uniformTypeMap.get(uniform);
if (type == "color3" || type == "color4") {
extraUniforms += `uniform ${type.replace("color", "float")} ${uniform};\n`;
} else {
extraUniforms += `uniform ${type} ${uniform};\n`;
}
const declarationType = getUniformDeclarationType(type);
extraUniforms += `uniform ${declarationType} ${uniform};\n`;
});
extraUniforms += "////// End of user supplied inputs ////// \n";

const prog = `
// Inputs supplied by shaders.skia.org:
uniform float3 iResolution; // Viewport resolution (pixels)
uniform float iTime; // Shader playback time (s)
uniform float4 iMouse; // Mouse drag pos=.xy Click pos=.zw (pixels)
` + extraUniforms + shaderCodeInput.value;

Expand All @@ -664,18 +677,21 @@
const skcanvas = surface.getCanvas();

function drawFrame(canvas) {
const iTime = (Date.now() - startTimeMs) / 1000;
const uniforms = [
shaderWidth, shaderHeight, 1, // vec3 iResolution(x, y, z);
iTime, // iTime
mouseDragX, mouseDragY, mouseClickX, mouseClickY, // iMouse(x, y, z, w)
];
customUniforms.forEach(function (uniform) {
const value = previewUniformValue(uniform);
if (typeof value === "string" || typeof value === "number") {
uniforms.push(value);
if (uniform == "iTime") {
const iTime = (Date.now() - startTimeMs) / 1000;
uniforms.push(iTime);
} else {
uniforms.push(...value);
const value = previewUniformValue(uniform);
if (typeof value === "string" || typeof value === "number") {
uniforms.push(value);
} else {
uniforms.push(...value);
}
}
});

Expand Down Expand Up @@ -757,7 +773,7 @@
}); ////// END OF CANVAS KIT //////
}

loadShaderCode('julia');
loadPresetShaderCode('julia');

function showModal() {
var modal = document.getElementById("shaderInfo");
Expand All @@ -767,8 +783,10 @@
window.onmessage = async function (event) {
let msg = event.data.pluginMessage;
if (msg.msg == 'shaderCode') {
// Run the preset shader code.
clearUniforms();
shaderCodeInput.value = msg.code;
createShaderTimeUniform();
await runShader();
return;
}
Expand Down Expand Up @@ -819,6 +837,9 @@
case "int":
createShaderIntUniform(shaderUniform.uniformName, shaderUniform.uniformValue);
break;
case "iTime":
createShaderTimeUniform();
break;
}
console.log(`${shaderUniform.uniformName} ${shaderUniform.uniformType} = ${shaderUniform.uniformValue}`);
}
Expand Down
Loading