Shadertoy shaders in Game Engine problem...

I paste in a shadertoy.com shader into Blender’s Text Editor, and when i start it up with Terminal on my mac, I get this error:

Python error compiling script - object ‘Grid’, controller ‘and’:
File “Text”, line 7
const int NUM_STEPS = 8;

SyntaxError: invalid syntax

Blender Game Engine Started
Blender Game Engine Finished

No matter how much i try to correct the indentation or syntax error, it spits out that error. I don’t really know how to code my own GLSL shaders, or any other stuff, but manipulate them. Here’s the script so far:

import bge
from bge import logic
cont = Gamelogic.getCurrentController()
own = cont.getOwner()
import math

const int NUM_STEPS = 8;
const float PI = 3.1415;
const float EPSILON = 1e-3;
float EPSILON_NRM = 0.1 / iResolution.x;

// sea
const int ITER_GEOMETRY = 3;
const int ITER_FRAGMENT = 5;
const float SEA_HEIGHT = 0.6;
const float SEA_CHOPPY = 4.0;
const float SEA_SPEED = 0.8;
const float SEA_FREQ = 0.16;
const vec3 SEA_BASE = vec3(0.1,0.19,0.22);
const vec3 SEA_WATER_COLOR = vec3(0.8,0.9,0.6);
float SEA_TIME = 1.0 + iGlobalTime * SEA_SPEED;
mat2 octave_m = mat2(1.6,1.2,-1.2,1.6);

// math
mat3 fromEuler(vec3 ang) {
vec2 a1 = vec2(sin(ang.x),cos(ang.x));
vec2 a2 = vec2(sin(ang.y),cos(ang.y));
vec2 a3 = vec2(sin(ang.z),cos(ang.z));
mat3 m;
m[0] = vec3(a1.ya3.y+a1.xa2.xa3.x,a1.ya2.xa3.x+a3.ya1.x,-a2.ya3.x);
m[1] = vec3(-a2.y
a1.x,a1.ya2.y,a2.x);
m[2] = vec3(a3.y
a1.xa2.x+a1.ya3.x,a1.xa3.x-a1.ya3.ya2.x,a2.ya3.y);
return m;
}
float hash( vec2 p ) {
float h = dot(p,vec2(127.1,311.7));
return fract(sin(h)43758.5453123);
}
float noise( in vec2 p ) {
vec2 i = floor( p );
vec2 f = fract( p );
vec2 u = f
f*(3.0-2.0f);
return -1.0+2.0
mix( mix( hash( i + vec2(0.0,0.0) ),
hash( i + vec2(1.0,0.0) ), u.x),
mix( hash( i + vec2(0.0,1.0) ),
hash( i + vec2(1.0,1.0) ), u.x), u.y);
}

// lighting
float diffuse(vec3 n,vec3 l,float p) {
return pow(dot(n,l) * 0.4 + 0.6,p);
}
float specular(vec3 n,vec3 l,vec3 e,float s) {
float nrm = (s + 8.0) / (3.1415 * 8.0);
return pow(max(dot(reflect(e,n),l),0.0),s) * nrm;
}

// sky
vec3 getSkyColor(vec3 e) {
e.y = max(e.y,0.0);
return vec3(pow(1.0-e.y,2.0), 1.0-e.y, 0.6+(1.0-e.y)*0.4);
}

// sea
float sea_octave(vec2 uv, float choppy) {
uv += noise(uv);
vec2 wv = 1.0-abs(sin(uv));
vec2 swv = abs(cos(uv));
wv = mix(wv,swv,wv);
return pow(1.0-pow(wv.x * wv.y,0.65),choppy);
}

float map(vec3 p) {
float freq = SEA_FREQ;
float amp = SEA_HEIGHT;
float choppy = SEA_CHOPPY;
vec2 uv = p.xz; uv.x *= 0.75;

float d, h = 0.0;    
for(int i = 0; i < ITER_GEOMETRY; i++) {        
    d = sea_octave((uv+SEA_TIME)*freq,choppy);
    d += sea_octave((uv-SEA_TIME)*freq,choppy);
    h += d * amp;        
    uv *= octave_m; freq *= 1.9; amp *= 0.22;
    choppy = mix(choppy,1.0,0.2);
}
return p.y - h;

}

float map_detailed(vec3 p) {
float freq = SEA_FREQ;
float amp = SEA_HEIGHT;
float choppy = SEA_CHOPPY;
vec2 uv = p.xz; uv.x *= 0.75;

float d, h = 0.0;    
for(int i = 0; i < ITER_FRAGMENT; i++) {        
    d = sea_octave((uv+SEA_TIME)*freq,choppy);
    d += sea_octave((uv-SEA_TIME)*freq,choppy);
    h += d * amp;        
    uv *= octave_m; freq *= 1.9; amp *= 0.22;
    choppy = mix(choppy,1.0,0.2);
}
return p.y - h;

}

vec3 getSeaColor(vec3 p, vec3 n, vec3 l, vec3 eye, vec3 dist) {
float fresnel = clamp(1.0 - dot(n,-eye), 0.0, 1.0);
fresnel = pow(fresnel,3.0) * 0.65;

vec3 reflected = getSkyColor(reflect(eye,n));    
vec3 refracted = SEA_BASE + diffuse(n,l,80.0) * SEA_WATER_COLOR * 0.12; 

vec3 color = mix(refracted,reflected,fresnel);

float atten = max(1.0 - dot(dist,dist) * 0.001, 0.0);
color += SEA_WATER_COLOR * (p.y - SEA_HEIGHT) * 0.18 * atten;

color += vec3(specular(n,l,eye,60.0));

return color;

}

// tracing
vec3 getNormal(vec3 p, float eps) {
vec3 n;
n.y = map_detailed§;
n.x = map_detailed(vec3(p.x+eps,p.y,p.z)) - n.y;
n.z = map_detailed(vec3(p.x,p.y,p.z+eps)) - n.y;
n.y = eps;
return normalize(n);
}

float heightMapTracing(vec3 ori, vec3 dir, out vec3 p) {
float tm = 0.0;
float tx = 1000.0;
float hx = map(ori + dir * tx);
if(hx > 0.0) return tx;
float hm = map(ori + dir * tm);
float tmid = 0.0;
for(int i = 0; i < NUM_STEPS; i++) {
tmid = mix(tm,tx, hm/(hm-hx));
p = ori + dir * tmid;
float hmid = map§;
if(hmid < 0.0) {
tx = tmid;
hx = hmid;
} else {
tm = tmid;
hm = hmid;
}
}
return tmid;
}

// main
void mainImage( out vec4 fragColor, in vec2 fragCoord ) {
vec2 uv = fragCoord.xy / iResolution.xy;
uv = uv * 2.0 - 1.0;
uv.x = iResolution.x / iResolution.y;
float time = iGlobalTime * 0.3 + iMouse.x
0.01;

// ray
vec3 ang = vec3(sin(time*3.0)*0.1,sin(time)*0.2+0.3,time);    
vec3 ori = vec3(0.0,3.5,time*5.0);
vec3 dir = normalize(vec3(uv.xy,-2.0)); dir.z += length(uv) * 0.15;
dir = normalize(dir) * fromEuler(ang);

// tracing
vec3 p;
heightMapTracing(ori,dir,p);
vec3 dist = p - ori;
vec3 n = getNormal(p, dot(dist,dist) * EPSILON_NRM);
vec3 light = normalize(vec3(0.0,1.0,0.8)); 
         
// color
vec3 color = mix(
    getSkyColor(dir),
    getSeaColor(p,n,light,dir,dist),
    pow(smoothstep(0.0,-0.05,dir.y),0.3));
    
// post
fragColor = vec4(pow(color,vec3(0.75)), 1.0);

}
“”"

cont = logic.getCurrentController()
own = cont.owner
mesh = own.meshes[0]
for mat in mesh.materials:
shader = mat.getShader()
if shader != None:
if not shader.isValid():
print(“Setting shader source code.”)
shader.setSource(vertex, fragment, 1)

My goal is to simulate water with waves much like Martinsh did, and apply it to an object. Upon starting the Game Engine, you’d see reflection, refraction and a nice ocean object with moving waves that i could use for my own games. Can someone please help me out, and solve this issue?

@Chompy

You forgot the

fragment = """

On line 6.

In any case, it won’t work anyway. Shadertoy shaders are not compatible with BGE without modifications, and for that you need at least a little understanding of GLSL. I recommend you to Install UPBGE+Community Addon and go here: http://coredoc.royalwebhosting.net/api/filter2D.html#installing-or-creating-custom-shaders

That pages contains a link of a tutorial “beginers guide to coding graphic shaders”, wich uses ShaderToy, and some guidelines into how to port ShaderToy shaders to BGE. The addon will make it much easier for you to send uniforms to shaders from Python so that you can easily test them. And if you look for the Texture 2DFilter it is the same as in the tutorial example but ported to BGE.

EDIT: About water, if you can wait, in a few months I’ll probably port it to the Community Addon. But for now I’m focusing in 2DFilters mainly (and, similar as they may be, 2DFilters and fragment shaders aren’t exactly the same at Python level).

Hi, that looks like a great link there. Been looking into this. One thing that confuses me is that I thought the point of GLSL was that the code could be ported to different applications ? Or is this just a case of “not that simple”. I wonder if there’s a Shadertoy to Blender converter out there ?

GLSL needs you to provide the input texture and the output, as well as any other parameters you may need. ShaderToy automatically does this for you, BGE also does some part of it, but they do it differently. When they say that GLSL code can be ported, it means that no matter the GPU or OS running behind your app, the GLSL code will work the same, as long as the parameters you provide are also the same. (I’ve taken some license here with the GL version and drivers)

GLSL is one of those things that you can only understand well when you try to make your own game engine with C/C++/OpenGL