Skip to content

Commit 2fd66e7

Browse files
author
Turtle1331
committed
Experiment with mobile VR support
1 parent b0e373b commit 2fd66e7

File tree

4 files changed

+384
-0
lines changed

4 files changed

+384
-0
lines changed

ios.html

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<html>
2+
<head>
3+
<meta charset="UTF-8">
4+
<script src="test.js"></script>
5+
<script src="ios.js"></script>
6+
<style>
7+
#canvas {
8+
position:fixed;
9+
left:0;
10+
top:0;
11+
width:100%;
12+
height:100%;
13+
}
14+
</style>
15+
</head>
16+
<body onload="main();">
17+
<canvas id="canvas" width=1000 height=1000></canvas>
18+
</body>
19+
</html>

ios.js

+242
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,242 @@
1+
// Name uniforms here, appear as fields in uniforms object from initUniforms()
2+
const myUniforms = [
3+
"resolution",
4+
"time",
5+
"mouse",
6+
"rotation",
7+
];
8+
9+
10+
11+
// Sets uniforms at start of program
12+
function setupUniforms(gl, uniforms, vars) {
13+
const canvas = document.getElementById("canvas");
14+
gl.uniform2f(uniforms.resolution, canvas.width, canvas.height);
15+
gl.uniform1f(uniforms.time, vars.time);
16+
gl.uniform2f(uniforms.mouse, 0, 0);
17+
}
18+
19+
// Sets uniforms before rendering each frame
20+
function updateUniforms(gl, uniforms, vars) {
21+
gl.uniform1f(uniforms.time, vars.time);
22+
gl.uniform3f(uniforms.rotation, vars.rotation[0], vars.rotation[1], vars.rotation[2]);
23+
}
24+
25+
26+
27+
////////////////////////////////////////////////////////////////////////////////
28+
29+
30+
31+
// Call when page loads
32+
function main() {
33+
const canvas = document.getElementById("canvas");
34+
35+
// Initialize WebGL rendering context
36+
const gl = canvas.getContext("webgl");
37+
if (!gl) {
38+
alert("WebGL initialization failed. Please check if your browser supports it.");
39+
return;
40+
}
41+
42+
// Initialize shader program and position buffer
43+
const shaderProgram = initShaderProgram(gl);
44+
const posBuffer = initBuffer(gl);
45+
46+
// Setup shader program with uniforms and vertices
47+
const uniforms = initUniforms(gl, shaderProgram, myUniforms);
48+
const program = {
49+
program: shaderProgram,
50+
vertices: gl.getAttribLocation(shaderProgram, "vPosition"),
51+
posBuffer: posBuffer
52+
};
53+
prepareScene(gl, program, uniforms);
54+
55+
56+
// Setup uniform vlaues
57+
const vars = {"time": 0, "dt": 0, "rotation": [0, 0, 0]};
58+
canvas.vars = vars;
59+
setupUniforms(gl, uniforms, vars);
60+
61+
// Render loop
62+
function render(elapsed) {
63+
// Calculate time values
64+
vars.dt = elapsed / 1000 - vars.time;
65+
vars.time = elapsed / 1000;
66+
67+
// Update uniform values
68+
updateUniforms(gl, uniforms, vars);
69+
70+
// Render to screen
71+
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
72+
requestAnimationFrame(render);
73+
}
74+
// Loop
75+
requestAnimationFrame(render);
76+
77+
// Add fullscreen
78+
fullScreen();
79+
80+
// Add device orientation sensing
81+
window.addEventListener("deviceorientation", handleOrientation, true);
82+
}
83+
84+
85+
86+
//
87+
function handleOrientation(event) {
88+
//alert(event.alpha + " " + event.beta + " " + event.gamma);
89+
canvas.vars.rotation = [event.beta, event.gamma, event.alpha];
90+
}
91+
92+
93+
94+
//
95+
function fullScreen() {
96+
const canvas = document.getElementById("canvas");
97+
98+
// Find available fullscreen and pointerlock methods
99+
canvas.requestFullscreen = canvas.requestFullscreen ||
100+
canvas.mozRequestFullScreen ||
101+
canvas.webkitRequestFullscreen;
102+
103+
document.exitFullscreen = document.exitFullscreen ||
104+
document.mozCancelFullScreen ||
105+
document.webkitExitFullscreen;
106+
107+
canvas.requestPointerLock = canvas.requestPointerLock ||
108+
canvas.mozRequestPointerLock ||
109+
canvas.webkitRequestPointerLock;
110+
111+
document.exitPointerLock = document.exitPointerLock ||
112+
document.mozExitPointerLock ||
113+
document.webkitExitPointerLock;
114+
115+
// Add pointer lock listener
116+
document.addEventListener('pointerlockchange', pointerLockChange, false);
117+
document.addEventListener('mozpointerlockchange', pointerLockChange, false);
118+
document.addEventListener('webkitpointerlockchange', pointerLockChange, false);
119+
120+
// Add mouse listener
121+
document.addEventListener("mousemove", onmousemove, false);
122+
123+
// Fullscreen and pointer lock on click
124+
canvas.onclick = function() {
125+
canvas.requestFullscreen();
126+
canvas.onmousemove = canvas.requestPointerLock;
127+
}
128+
}
129+
130+
function pointerLockChange() {
131+
// Check if pointer just locked or unlocked
132+
}
133+
134+
function onmousemove() {
135+
// pass
136+
}
137+
138+
139+
140+
////////////////////////////////////////////////////////////////////////////////
141+
142+
143+
144+
// Helper for linking shader programs
145+
function initShaderProgram(gl) {
146+
const vsh = loadShader(gl, gl.VERTEX_SHADER, vsh_src);
147+
const fsh = loadShader(gl, gl.FRAGMENT_SHADER, fsh_src);
148+
149+
// Create the shader program
150+
const shaderProgram = gl.createProgram();
151+
gl.attachShader(shaderProgram, vsh);
152+
gl.attachShader(shaderProgram, fsh);
153+
gl.linkProgram(shaderProgram);
154+
155+
// Check for errors in setup
156+
if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
157+
alert('Shader program initialization failed: ' + gl.getProgramInfoLog(shaderProgram));
158+
return;
159+
}
160+
161+
return shaderProgram;
162+
}
163+
164+
165+
166+
// Helper for compiling shader source
167+
function loadShader(gl, type, src) {
168+
const shader = gl.createShader(type);
169+
170+
// Compile shader
171+
gl.shaderSource(shader, src);
172+
gl.compileShader(shader);
173+
174+
// Check for errors
175+
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
176+
alert('An error occurred compiling the shaders: ' + gl.getShaderInfoLog(shader));
177+
gl.deleteShader(shader);
178+
return null;
179+
}
180+
181+
return shader;
182+
}
183+
184+
185+
186+
// Helper for initializing position buffer
187+
function initBuffer(gl) {
188+
// Create a buffer for the square's positions.
189+
const positionBuffer = gl.createBuffer();
190+
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
191+
192+
// Now create an array of positions for the square.
193+
const positions = [
194+
1.0, 1.0,
195+
-1.0, 1.0,
196+
1.0, -1.0,
197+
-1.0, -1.0,
198+
];
199+
200+
gl.bufferData(
201+
gl.ARRAY_BUFFER,
202+
new Float32Array(positions),
203+
gl.STATIC_DRAW);
204+
205+
return positionBuffer;
206+
}
207+
208+
209+
210+
// Helper for finishing setup for rendering
211+
function prepareScene(gl, program, uniforms) {
212+
// Clear screen
213+
gl.clearColor(0.0, 0.0, 0.0, 1.0);
214+
gl.clearDepth(1.0);
215+
216+
// Setup vertex position attribute as vec2
217+
gl.vertexAttribPointer(program.vertices, 2, gl.FLOAT, false, 0, 0);
218+
gl.enableVertexAttribArray(program.vertices);
219+
220+
// Set shader program
221+
gl.useProgram(program.program);
222+
223+
// Set uniforms
224+
const canvas = document.getElementById("canvas");
225+
}
226+
227+
228+
229+
// Helper for initializing uniforms
230+
function initUniforms(gl, shaderProgram, uniformNames) {
231+
var uniforms = {};
232+
var location;
233+
for (var i = 0; i < uniformNames.length; i++) {
234+
location = gl.getUniformLocation(shaderProgram, uniformNames[i]);
235+
if (location == -1) {
236+
alert("Uniform not found: " + uniformName);
237+
} else {
238+
uniforms[uniformNames[i]] = location;
239+
}
240+
}
241+
return uniforms;
242+
}

test.js

+118
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
const vsh_src = `
2+
precision highp float;
3+
4+
attribute vec4 vPosition;
5+
6+
void main() {
7+
gl_Position = vPosition.xyzw;
8+
}
9+
`;
10+
11+
const fsh_src = `
12+
precision highp float;
13+
14+
#define rot(a) mat2(cos(a), -sin(a), sin(a), cos(a))
15+
#define rotX(a) mat3(1, 0, 0, 0, cos(a), -sin(a), 0, sin(a), cos(a))
16+
#define rotY(a) mat3(cos(a), 0, -sin(a), 0, 1, 0, sin(a), 0, cos(a))
17+
#define rotZ(a) mat3(cos(a), -sin(a), 0, sin(a), cos(a), 0, 0, 0, 1)
18+
19+
const float PI = asin(1.) * 2.;
20+
const float EPSILON = 0.01;
21+
const float FAR = 12.;
22+
uniform float time;
23+
uniform vec2 resolution;
24+
uniform float rightEye;
25+
uniform vec3 rotation;
26+
27+
float df_sphere(vec3 p, float s) { return length(p) - s; }
28+
29+
float scene(vec3 p) {
30+
float d = FAR;
31+
d = min(d, df_sphere(p + vec3(0., .5, 0.), 1.));
32+
d = min(d, df_sphere(p + vec3(0., -.5, -2.), .5));
33+
d = min(d, df_sphere(p + vec3(-sqrt(3.), -.5, 1.), .5));
34+
d = min(d, df_sphere(p + vec3(sqrt(3.), -.5, 1.), .5));
35+
return d;
36+
}
37+
38+
float lighting(vec3 p, vec3 src) {
39+
vec3 e = normalize(src - p) * EPSILON / 2.;
40+
return (scene(p + e) - scene(p - e)) / EPSILON;
41+
}
42+
43+
void main() {
44+
gl_FragColor = vec2(0., 1.).xxxy;
45+
//if (mod(gl_FragCoord.x+gl_FragCoord.y, 6.)>1.) return;
46+
47+
vec2 uv = 0.8 * vec2(1.5, -1.) * ((gl_FragCoord.xy / resolution) - .5) * resolution / resolution.x + .5;
48+
//vec2 uv = 0.8 * vec2(1.5, -1.) * ((gl_FragCoord.yx / resolution.yx) - .5) * resolution.yx / resolution.y + .5;
49+
uv = uv * vec2(2., 1.);
50+
if (uv.x > 1.) uv.x -= 1.;
51+
//if (abs(uv.x - 1.) > 1.) return;
52+
float which = step(uv.y, .5);
53+
vec3 cam = vec3(0., 0., -5. - 5. * which);
54+
vec3 tgt = vec3(0., 0., 0.);
55+
56+
//cam.yz *= rot(-cos(time / 2. + 2. * which) * PI / 6. + PI / 6. * which);
57+
//cam.xz *= rot(time * (2. * which - 1.));
58+
//vec3 front = normalize(tgt - cam);
59+
//vec3 right = normalize(cross(front, vec3(0., 1., 0.)));
60+
//vec3 up = cross(right, front);
61+
62+
vec3 one = vec3(0, 1, -1);
63+
float pi = 2. * asin(1.);
64+
float rad = pi / 180.;
65+
vec3 right, up, front;
66+
right = one.yxx;
67+
up = one.xyx;
68+
front = one.xxy;
69+
mat3 psp = mat3(right, up, front);
70+
71+
//psp *= rotZ(rotation.y * rad);
72+
//psp *= rotX(-rotation.z * rad);
73+
//psp *= rotX(-pi / 2.);
74+
//psp *= rotY(rotation.x * rad);
75+
76+
//cam.yz *= rot(-pi / 2.);
77+
right = one.yxx;
78+
up = one.xyx;
79+
front = one.xxy;
80+
psp = mat3(right, up, front);
81+
psp *= rotX(rotation.x * rad);
82+
psp *= rotY(rotation.y * rad);
83+
psp *= rotZ(-rotation.z * rad);
84+
85+
//psp *= rotZ(rotation.y * sign(rotation.z) * rad + pi * sign(rotation.z));
86+
//psp *= rotX(-rotation.z * rad);
87+
//psp *= rotX(pi / 2.);
88+
//psp *= rotY(-rotation.x * rad);
89+
90+
cam *= psp;
91+
front *= psp;
92+
right *= psp;
93+
up *= psp;
94+
95+
uv = (uv * vec2(1., 2.)) - .5;
96+
uv.y = fract(uv.y + .5) - .5;
97+
vec3 dir = normalize(front * 1. + right * uv.x + up * uv.y);
98+
float eye = step(gl_FragCoord.x, resolution.x * .5) - .5;
99+
//float eye = step(gl_FragCoord.y, resolution.y * .5) - .5;
100+
eye *= -0.5;
101+
cam += right * eye;
102+
float dist = 0.;
103+
float d = 0.;
104+
for (int i = 0; i < 30; i++) {
105+
d = scene(cam + dist * dir);
106+
dist += d;
107+
if (d < EPSILON || dist > FAR) break;
108+
}
109+
float n = 0.;
110+
if (d < EPSILON) {
111+
n = max(0., lighting(cam + dist * dir, vec3(-4.))) + .2;
112+
}
113+
//float n = 1. - .2 * dist;
114+
gl_FragColor = vec2(n, 1.).xxxy;
115+
if (length(cam + dist * dir + vec3(0., .5, 0.)) > 1. + EPSILON) gl_FragColor.rg *= .5;
116+
else gl_FragColor.gb *= .5; //gl_FragColor = vec4(uv.x, 0., uv.y, 1.); //gl_FragColor.rgb = 1. - clamp(gl_FragColor.rgb, vec3(0.), vec3(1.)) * 1.;
117+
}
118+
`;

test.js~

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
const vsh_src = `
2+
precision highp float;
3+
#define rot(a) mat2(cos(a), -sin(a), sin(a), cos(a))
4+
const float PI = asin(1.) * 2.; const float EPSILON = 0.01; const float FAR = 12.; uniform float u_time; uniform vec2 resolution; uniform float rightEye; varying vec2 v_tex_coord; float df_sphere(vec3 p, float s) { return length(p) - s; } float scene(vec3 p) { float d = FAR; d = min(d, df_sphere(p + vec3(0., .5, 0.), 1.)); d = min(d, df_sphere(p + vec3(0., -.5, -2.), .5)); d = min(d, df_sphere(p + vec3(-sqrt(3.), -.5, 1.), .5)); d = min(d, df_sphere(p + vec3(sqrt(3.), -.5, 1.), .5)); return d; } float lighting(vec3 p, vec3 src) { vec3 e = normalize(src - p) * EPSILON / 2.; return (scene(p + e) - scene(p - e)) / EPSILON; } void main() { gl_FragColor = vec2(0., 1.).xxxy; if (mod(gl_FragCoord.x+gl_FragCoord.y, 4.)>0.) return; vec2 uv = vec2(1., -.5) * (v_tex_coord - .5) * resolution / resolution.x + .5; if (abs(uv.y - .5) > .5) return; float which = step(uv.y, .5); vec3 cam = vec3(0., 0., 5. + 5. * which); vec3 tgt = vec3(0., 0., 0.); cam.yz *= rot(-cos(u_time / 2. + 2. * which) * PI / 6. + PI / 6. * which); cam.xz *= rot(u_time * (2. * which - 1.)); vec3 front = normalize(tgt - cam); vec3 right = normalize(cross(front, vec3(0., 1., 0.))); vec3 up = cross(right, front); uv = fract(uv * vec2(1., 2.)) - .5; vec3 dir = normalize(front * 1. + right * uv.x + up * uv.y); float eye = (rightEye - .5); cam += right * eye; float dist = 0.; float d = 0.; for (int i = 0; i < 30; i++) { d = scene(cam + dist * dir); dist += d; if (d < EPSILON || dist > FAR) break; } float n = 0.; if (d < EPSILON) { n = max(0., lighting(cam + dist * dir, vec3(-4.))) + .2; } //float n = 1. - .2 * dist; gl_FragColor = vec2(n, 1.).xxxy; if (length(cam + dist * dir + vec3(0., .5, 0.)) > 1. + EPSILON) gl_FragColor.rg *= .5; else gl_FragColor.gb *= .5; //gl_FragColor = vec4(uv.x, 0., uv.y, 1.); //gl_FragColor.rgb = 1. - clamp(gl_FragColor.rgb, vec3(0.), vec3(1.)) * 1.; }
5+
`;

0 commit comments

Comments
 (0)