Skip to content

Commit

Permalink
Add json example
Browse files Browse the repository at this point in the history
  • Loading branch information
Vipitis committed Feb 27, 2024
1 parent 4287ddc commit 0cefc2e
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 5 deletions.
52 changes: 52 additions & 0 deletions examples/shader_MllSzX.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
{
"Shader": {
"ver": "0.1",
"info": {
"id": "MllSzX",
"date": "1438698189",
"viewed": 14064,
"name": "Bicubic Texture Filtering",
"username": "demofox",
"description": "Nearest neighbor texture filtering on left, Bilinear texture filtering in left middle, Lagrange Bicubic texture filtering on middle right, cubic hermite on the right. Use the mouse to control pan / zoom.\n",
"likes": 61,
"published": 3,
"flags": 0,
"usePreview": 0,
"tags": [
"2d",
"texturefilter"
],
"hasliked": 0
},
"renderpass": [
{
"inputs": [
{
"id": 16,
"src": "/media/a/3083c722c0c738cad0f468383167a0d246f91af2bfa373e9c5c094fb8c8413e0.png",
"ctype": "texture",
"channel": 0,
"sampler": {
"filter": "mipmap",
"wrap": "repeat",
"vflip": "false",
"srgb": "false",
"internal": "byte"
},
"published": 1
}
],
"outputs": [
{
"id": 37,
"channel": 0
}
],
"code": "float c_textureSize = 64.0;\n\n#define c_onePixel (1.0 / c_textureSize)\n#define c_twoPixels (2.0 / c_textureSize)\n\nfloat c_x0 = -1.0;\nfloat c_x1 = 0.0;\nfloat c_x2 = 1.0;\nfloat c_x3 = 2.0;\n \n//=======================================================================================\nvec3 CubicLagrange (vec3 A, vec3 B, vec3 C, vec3 D, float t)\n{\n return\n A * \n (\n (t - c_x1) / (c_x0 - c_x1) * \n (t - c_x2) / (c_x0 - c_x2) *\n (t - c_x3) / (c_x0 - c_x3)\n ) +\n B * \n (\n (t - c_x0) / (c_x1 - c_x0) * \n (t - c_x2) / (c_x1 - c_x2) *\n (t - c_x3) / (c_x1 - c_x3)\n ) +\n C * \n (\n (t - c_x0) / (c_x2 - c_x0) * \n (t - c_x1) / (c_x2 - c_x1) *\n (t - c_x3) / (c_x2 - c_x3)\n ) + \n D * \n (\n (t - c_x0) / (c_x3 - c_x0) * \n (t - c_x1) / (c_x3 - c_x1) *\n (t - c_x2) / (c_x3 - c_x2)\n );\n}\n\n//=======================================================================================\nvec3 BicubicLagrangeTextureSample (vec2 P)\n{\n vec2 pixel = P * c_textureSize + 0.5;\n \n vec2 frac = fract(pixel);\n pixel = floor(pixel) / c_textureSize - vec2(c_onePixel/2.0);\n \n vec3 C00 = texture(iChannel0, pixel + vec2(-c_onePixel ,-c_onePixel)).rgb;\n vec3 C10 = texture(iChannel0, pixel + vec2( 0.0 ,-c_onePixel)).rgb;\n vec3 C20 = texture(iChannel0, pixel + vec2( c_onePixel ,-c_onePixel)).rgb;\n vec3 C30 = texture(iChannel0, pixel + vec2( c_twoPixels,-c_onePixel)).rgb;\n \n vec3 C01 = texture(iChannel0, pixel + vec2(-c_onePixel , 0.0)).rgb;\n vec3 C11 = texture(iChannel0, pixel + vec2( 0.0 , 0.0)).rgb;\n vec3 C21 = texture(iChannel0, pixel + vec2( c_onePixel , 0.0)).rgb;\n vec3 C31 = texture(iChannel0, pixel + vec2( c_twoPixels, 0.0)).rgb; \n \n vec3 C02 = texture(iChannel0, pixel + vec2(-c_onePixel , c_onePixel)).rgb;\n vec3 C12 = texture(iChannel0, pixel + vec2( 0.0 , c_onePixel)).rgb;\n vec3 C22 = texture(iChannel0, pixel + vec2( c_onePixel , c_onePixel)).rgb;\n vec3 C32 = texture(iChannel0, pixel + vec2( c_twoPixels, c_onePixel)).rgb; \n \n vec3 C03 = texture(iChannel0, pixel + vec2(-c_onePixel , c_twoPixels)).rgb;\n vec3 C13 = texture(iChannel0, pixel + vec2( 0.0 , c_twoPixels)).rgb;\n vec3 C23 = texture(iChannel0, pixel + vec2( c_onePixel , c_twoPixels)).rgb;\n vec3 C33 = texture(iChannel0, pixel + vec2( c_twoPixels, c_twoPixels)).rgb; \n \n vec3 CP0X = CubicLagrange(C00, C10, C20, C30, frac.x);\n vec3 CP1X = CubicLagrange(C01, C11, C21, C31, frac.x);\n vec3 CP2X = CubicLagrange(C02, C12, C22, C32, frac.x);\n vec3 CP3X = CubicLagrange(C03, C13, C23, C33, frac.x);\n \n return CubicLagrange(CP0X, CP1X, CP2X, CP3X, frac.y);\n}\n\n//=======================================================================================\nvec3 CubicHermite (vec3 A, vec3 B, vec3 C, vec3 D, float t)\n{\n\tfloat t2 = t*t;\n float t3 = t*t*t;\n vec3 a = -A/2.0 + (3.0*B)/2.0 - (3.0*C)/2.0 + D/2.0;\n vec3 b = A - (5.0*B)/2.0 + 2.0*C - D / 2.0;\n vec3 c = -A/2.0 + C/2.0;\n \tvec3 d = B;\n \n return a*t3 + b*t2 + c*t + d;\n}\n\n//=======================================================================================\nvec3 BicubicHermiteTextureSample (vec2 P)\n{\n vec2 pixel = P * c_textureSize + 0.5;\n \n vec2 frac = fract(pixel);\n pixel = floor(pixel) / c_textureSize - vec2(c_onePixel/2.0);\n \n vec3 C00 = texture(iChannel0, pixel + vec2(-c_onePixel ,-c_onePixel)).rgb;\n vec3 C10 = texture(iChannel0, pixel + vec2( 0.0 ,-c_onePixel)).rgb;\n vec3 C20 = texture(iChannel0, pixel + vec2( c_onePixel ,-c_onePixel)).rgb;\n vec3 C30 = texture(iChannel0, pixel + vec2( c_twoPixels,-c_onePixel)).rgb;\n \n vec3 C01 = texture(iChannel0, pixel + vec2(-c_onePixel , 0.0)).rgb;\n vec3 C11 = texture(iChannel0, pixel + vec2( 0.0 , 0.0)).rgb;\n vec3 C21 = texture(iChannel0, pixel + vec2( c_onePixel , 0.0)).rgb;\n vec3 C31 = texture(iChannel0, pixel + vec2( c_twoPixels, 0.0)).rgb; \n \n vec3 C02 = texture(iChannel0, pixel + vec2(-c_onePixel , c_onePixel)).rgb;\n vec3 C12 = texture(iChannel0, pixel + vec2( 0.0 , c_onePixel)).rgb;\n vec3 C22 = texture(iChannel0, pixel + vec2( c_onePixel , c_onePixel)).rgb;\n vec3 C32 = texture(iChannel0, pixel + vec2( c_twoPixels, c_onePixel)).rgb; \n \n vec3 C03 = texture(iChannel0, pixel + vec2(-c_onePixel , c_twoPixels)).rgb;\n vec3 C13 = texture(iChannel0, pixel + vec2( 0.0 , c_twoPixels)).rgb;\n vec3 C23 = texture(iChannel0, pixel + vec2( c_onePixel , c_twoPixels)).rgb;\n vec3 C33 = texture(iChannel0, pixel + vec2( c_twoPixels, c_twoPixels)).rgb; \n \n vec3 CP0X = CubicHermite(C00, C10, C20, C30, frac.x);\n vec3 CP1X = CubicHermite(C01, C11, C21, C31, frac.x);\n vec3 CP2X = CubicHermite(C02, C12, C22, C32, frac.x);\n vec3 CP3X = CubicHermite(C03, C13, C23, C33, frac.x);\n \n return CubicHermite(CP0X, CP1X, CP2X, CP3X, frac.y);\n}\n\n//=======================================================================================\nvec3 BilinearTextureSample (vec2 P)\n{\n vec2 pixel = P * c_textureSize + 0.5;\n \n vec2 frac = fract(pixel);\n pixel = (floor(pixel) / c_textureSize) - vec2(c_onePixel/2.0);\n\n vec3 C11 = texture(iChannel0, pixel + vec2( 0.0 , 0.0)).rgb;\n vec3 C21 = texture(iChannel0, pixel + vec2( c_onePixel , 0.0)).rgb;\n vec3 C12 = texture(iChannel0, pixel + vec2( 0.0 , c_onePixel)).rgb;\n vec3 C22 = texture(iChannel0, pixel + vec2( c_onePixel , c_onePixel)).rgb;\n\n vec3 x1 = mix(C11, C21, frac.x);\n vec3 x2 = mix(C12, C22, frac.x);\n return mix(x1, x2, frac.y);\n}\n\n//=======================================================================================\nvec3 NearestTextureSample (vec2 P)\n{\n vec2 pixel = P * c_textureSize;\n \n vec2 frac = fract(pixel);\n pixel = (floor(pixel) / c_textureSize);\n return texture(iChannel0, pixel + vec2(c_onePixel/2.0)).rgb;\n}\n\n//=======================================================================================\nvoid AnimateUV (inout vec2 uv)\n{\n if (iMouse.z > 0.0)\n {\n uv -= vec2(0.0,0.5) * iResolution.y / iResolution.x;;\n uv *= vec2(iMouse.y / iResolution.y);\n uv += vec2(1.5 * iMouse.x / iResolution.x, 0.0);\n \n }\n else\n { \n \tuv += vec2(sin(iTime * 0.3)*0.5+0.5, sin(iTime * 0.7)*0.5+0.5);\n \tuv *= (sin(iTime * 0.3)*0.5+0.5)*3.0 + 0.2;\n }\n}\n\n//=======================================================================================\nvoid mainImage( out vec4 fragColor, in vec2 fragCoord )\n{\n // set up our coordinate system\n float aspectRatio = iResolution.y / iResolution.x;\n vec2 uv = (fragCoord.xy / iResolution.xy);\n uv.y *= aspectRatio;\n \n // do our sampling\n vec3 color;\n if (abs(uv.x - (1.0/4.0)) < 0.0025)\n {\n color = vec3(1.0);\n } \n else if (abs(uv.x - (2.0/4.0)) < 0.0025)\n {\n color = vec3(1.0);\n } \n else if (abs(uv.x - (3.0/4.0)) < 0.0025)\n {\n color = vec3(1.0);\n } \n else if (uv.x < (1.0/4.0))\n {\n AnimateUV(uv);\n color = NearestTextureSample(uv);\n }\n else if (uv.x < (2.0/4.0))\n {\n uv -= vec2((1.0/4.0),0.0);\n AnimateUV(uv);\n color = texture(iChannel0, uv).xyz;\n //color = BilinearTextureSample(uv);\n }\n else if (uv.x < (3.0/4.0))\n {\n uv -= vec2((2.0/4.0),0.0);\n AnimateUV(uv);\n color = BicubicLagrangeTextureSample(uv);\n }\n else\n {\n uv -= vec2((3.0/4.0),0.0);\n AnimateUV(uv);\n color = BicubicHermiteTextureSample(uv);\n\t}\n \n // set the final color\n\tfragColor = vec4(color,1.0); \n}",
"name": "Image",
"description": "",
"type": "image"
}
]
}
}
2 changes: 2 additions & 0 deletions examples/shadertoy_api.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# run_example = false

from wgpu_shadertoy import Shadertoy

# shadertoy source: https://www.shadertoy.com/view/wtcSzN by tdhooper CC-BY-NC-SA-3.0
Expand Down
9 changes: 9 additions & 0 deletions examples/shadertoy_json.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# run_example = false

from wgpu_shadertoy import Shadertoy

# shadertoy source: https://www.shadertoy.com/view/MllSzX by demofox CC-BY-NC-SA-3.0
shader = Shadertoy.from_json(".\examples\shader_MllSzX.json")

if __name__ == "__main__":
shader.show()
32 changes: 27 additions & 5 deletions wgpu_shadertoy/api.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import json
import os

import numpy as np
Expand All @@ -6,21 +7,32 @@

from .inputs import ShadertoyChannel

HEADERS = {"user-agent": "https://github.com/pygfx/shadertoy script"}


# TODO: write function that gives a good error message
def _get_api_key():
key = os.environ.get("SHADERTOY_KEY", None)
if key is None:
raise Exception(
raise ValueError(
"SHADERTOY_KEY environment variable not set, please set it to your Shadertoy API key to use API features. Follow the instructions at https://www.shadertoy.com/howto#q2"
)
test_url = "https://www.shadertoy.com/api/v1/shaders/query/test"
test_response = requests.get(test_url, params={"key": key}, headers=HEADERS)
if test_response.status_code != 200:
raise requests.exceptions.HTTPError(
f"Failed to use ShaderToy API with key: {test_response.status_code}"
)
test_response = test_response.json()
if "Error" in test_response:
raise ValueError(
f"Failed to use ShaderToy API with key: {test_response['Error']}"
)
return key


API_KEY = _get_api_key()

HEADERS = {"user-agent": "https://github.com/pygfx/shadertoy script"}


# TODO: consider caching media locally?
def _download_media_channels(inputs):
Expand All @@ -44,6 +56,16 @@ def _download_media_channels(inputs):
return list(channels.values())


def _save_json(data, path):
with open(path, "w") as f:
json.dump(data, f, indent=2)


def _load_json(path):
with open(path, "r") as f:
return json.load(f)


def shadertoy_from_id(id_or_url) -> dict:
"""
Fetches a shader from Shadertoy.com by its ID (or url) and returns the JSON data as dict.
Expand All @@ -70,8 +92,8 @@ def shader_args_from_json(dict_or_path, **kwargs):
"""
Builds a `Shadertoy` instance from a JSON-like dict of Shadertoy.com shader data.
"""
if isinstance(dict_or_path, str):
raise NotImplementedError("Loading from file not yet implemented")
if isinstance(dict_or_path, (str, os.PathLike)):
shader_data = _load_json(dict_or_path)
else:
shader_data = dict_or_path

Expand Down

0 comments on commit 0cefc2e

Please sign in to comment.