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

Custom parameters for ShaderToys and custom textures #181

Open
Dakotys opened this issue May 11, 2024 · 4 comments
Open

Custom parameters for ShaderToys and custom textures #181

Dakotys opened this issue May 11, 2024 · 4 comments

Comments

@Dakotys
Copy link
Contributor

Dakotys commented May 11, 2024

For some reason Shader Toys hasn't been updated for some time and is lacking a lot of features.
I made a snippet code that reads parameters defined in Common tab and expands Shader Toys capabilities based on them.
So far I was only in need of custom images, so that is the first thing I implemented. Now its possible to add images from URL and also base64 encoded images.

Check this shader and also it's Common tab.

And run this code:

function getParameters() {
	// get id of common tab
	const commonTabImg = document.querySelector("img[src='/img/common.png']");
	if (!commonTabImg) return {};
	const commonTabId = Number.parseInt(commonTabImg.parentNode.id[3]);

	// get content of common tab
	const content = window.gShaderToy.mPass[commonTabId].mDocs.getValue();

	// get parameters from content
	const match = content.match(
		/\/\*[\s]*shadertoy-plugin parameters[\s\S]*?\*\//,
	); // Match the parameters comment block

	if (!match) return {};

	const parametersString = match[0]
		.replace(/\/\*\s*shadertoy-plugin parameters\s*/, "") // Remove the comment marker at start and "shadertoy-plugin parameters" line
		.replace(/\*\//, "") // Remove the closing comment marker
		.trim();

	try {
		return JSON.parse(parametersString); // Parse the parameters string as JSON
	} catch (error) {
		console.error("Error parsing shader parameters:", error);
		console.error(parametersString);
		return {};
	}
}

function evaluateParameters() {
	const params = getParameters();

	if (params.textures) {
		params.textures.forEach((texture, index) => {
			window.gShaderToy.mEffect.NewTexture(0, index, {
				mSrc: texture,
				mType: "texture",
				mID: 0,
				mSampler: {
					filter: "mipmap",
					wrap: "repeat",
					vflip: "true",
					srgb: "false",
					internal: "byte",
				},
			});
		});
	}
}

evaluateParameters();

In the mean time anyone interested in including own images in shaderToys can use this extension and let it run the above mentioned script.
Just add a comment anywhere inside Common tab that is in code block ( /* */ )
and on the second line has line " shadertoy-plugin parameters " and follows by json. Check this shader for more info.

I know it was mentioned before, but not implemented. #101

@Dakotys Dakotys changed the title Custom parameters for ShaderToys Custom parameters for ShaderToys and custom images May 11, 2024
@Dakotys Dakotys changed the title Custom parameters for ShaderToys and custom images Custom parameters for ShaderToys and custom textures May 11, 2024
@Dakotys
Copy link
Contributor Author

Dakotys commented May 11, 2024

code i use inside the user-javascript extension:

function getParameters() {
	// get id of common tab
	const commonTabImg = document.querySelector("img[src='/img/common.png']");
	if (!commonTabImg) return {};
	const commonTabId = Number.parseInt(commonTabImg.parentNode.id[3]);

	// get content of common tab
	const content = window.gShaderToy.mPass[commonTabId].mDocs.getValue();

	// get parameters from content
	const match = content.match(
		/\/\*[\s]*shadertoy-plugin parameters[\s\S]*?\*\//
	); // Match the parameters comment block

	if (!match) return {};

	const parametersString = match[0]
		.replace(/\/\*\s*shadertoy-plugin parameters\s*/, '') // Remove the comment marker at start and "shadertoy-plugin parameters" line
		.replace(/\*\//, '') // Remove the closing comment marker
		.trim();

	try {
		return JSON.parse(parametersString); // Parse the parameters string as JSON
	} catch (error) {
		console.error('Error parsing shader parameters:', error);
		console.error(parametersString);
		return {};
	}
}

function evaluateParameters() {
	const params = getParameters();

	if (params.textures) {
		params.textures.forEach((texture, index) => {
			window.gShaderToy.mEffect.NewTexture(0, index, {
				mSrc: texture,
				mType: 'texture',
				mID: 0,
				mSampler: {
					filter: 'mipmap',
					wrap: 'repeat',
					vflip: 'true',
					srgb: 'false',
					internal: 'byte',
				},
			});
		});
	}
}

const originalSend = XMLHttpRequest.prototype.send;
XMLHttpRequest.prototype.send = function () {
	const xhr = this;
	xhr.addEventListener('load', function () {
		if (xhr.responseURL == 'https://www.shadertoy.com/shadertoy') {
			setTimeout(evaluateParameters, 300);
		}
	});
	return originalSend.apply(xhr, arguments);
};

window.addEventListener('load', function () {
	const compileButton = document.getElementById('compileButton');
	compileButton.addEventListener('click', function () {
		evaluateParameters();
	});
});

@patuwwy
Copy link
Owner

patuwwy commented May 12, 2024

Do I understand correctly that you are cheating CORS in Response? Epic.

@Dakotys
Copy link
Contributor Author

Dakotys commented May 12, 2024

In this case no, I just needed a way to listen to when images where loaded because it sometimes happened that wrong preview was displayed in channels on site load even thought correct textures were applied inside shader
image_2024-05-12_030500529

@patuwwy
Copy link
Owner

patuwwy commented May 12, 2024

kk, could you make a pull request?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants