Milestone 1:

Tuned Ace Editor a bit.
Added multiple textures.
Optimized shader, get ready for Recursive Ray Tracing.
master
bill 4 years ago
parent 107bbb23cd
commit afc8716507

@ -100,6 +100,13 @@ let vs = my_vertex_shader.innerHTML;
// START EVERYTHING. // START EVERYTHING.
gl_start(canvas1, vs, fs); gl_start(canvas1, vs, fs);
editor.getSession().setValue(fs); editor.getSession().setValue(fs);
editor.session.on('change', function(delta) {
if(typeof canvas1.setShaders === "function")
{
canvas1.setShaders(vs, editor.getSession().getValue());
setUniform('1i', 'flags', flags);
}
});
} }
client.send(); client.send();
document.body.innerHTML = ['' document.body.innerHTML = [''
@ -134,10 +141,7 @@ editor.setOptions({
}); });
editor.setAutoScrollEditorIntoView(true); editor.setAutoScrollEditorIntoView(true);
// REPARSE THE SHADER PROGRAM AFTER EVERY KEYSTROKE. // REPARSE THE SHADER PROGRAM AFTER EVERY KEYSTROKE.
editor.session.on('change', function(delta) {
if(typeof canvas1.setShaders === "function")
canvas1.setShaders(vs, editor.getSession().getValue());
});
let lastTime = Date.now(); let lastTime = Date.now();
let animating = true; let animating = true;
let ctrl = false; let ctrl = false;
@ -156,7 +160,7 @@ document.addEventListener('keydown',(e)=>{
else if(ctrl && e.code == 'KeyT') else if(ctrl && e.code == 'KeyT')
{ {
mask = 0x1; mask = 0x1;
flags = flags&!mask | (!(flags&mask)?0:mask); flags = flags&!mask | (!(flags&mask)?mask:0);
setUniform('1i', 'flags', flags); setUniform('1i', 'flags', flags);
} }
else if (ctrl && e.code == 'KeyS') else if (ctrl && e.code == 'KeyS')

@ -32,34 +32,35 @@ function getBlob(data) {
return new Blob([new Uint8Array(bytes)]); return new Blob([new Uint8Array(bytes)]);
} }
let texture = [], gl, program; let texture = [], gl, program;
let textures = [0, 1]; let textures = [];
let lock = false;
function loadTexture(gl, url, i) { function loadTexture(gl, url, i) {
const level = 0;
const internalFormat = gl.RGBA;
const width = 1;
const height = 1;
const border = 0;
const srcFormat = gl.RGBA;
const srcType = gl.UNSIGNED_BYTE;
if (texture[i] == null) if (texture[i] == null)
{ {
texture[i] = gl.createTexture(); texture[i] = gl.createTexture();
const pixel = new Uint8Array([0, 0, 255, 255]); // opaque blue
gl.activeTexture(gl.TEXTURE0+i);
gl.bindTexture(gl.TEXTURE_2D, texture[i]); gl.bindTexture(gl.TEXTURE_2D, texture[i]);
gl.texImage2D(gl.TEXTURE_2D, level, internalFormat,
width, height, border, srcFormat, srcType,
pixel);
} }
// Because images have to be downloaded over the internet // Because images have to be downloaded over the internet
// they might take a moment until they are ready. // they might take a moment until they are ready.
// Until then put a single pixel in the texture so we can // Until then put a single pixel in the texture so we can
// use it immediately. When the image has finished downloading // use it immediately. When the image has finished downloading
// we'll update the texture with the contents of the image. // we'll update the texture with the contents of the image.
const level = 0;
const internalFormat = gl.RGBA;
const width = 1;
const height = 1;
const border = 0;
const srcFormat = gl.RGBA;
const srcType = gl.UNSIGNED_BYTE;
const pixel = new Uint8Array([0, 0, 255, 255]); // opaque blue
gl.texImage2D(gl.TEXTURE_2D, level, internalFormat,
width, height, border, srcFormat, srcType,
pixel);
const image = new Image(); const image = new Image();
image.onload = function () { image.onload = function () {
errorMessage.innerHTML += image.src + i; gl.activeTexture(gl.TEXTURE0+i);
gl.bindTexture(gl.TEXTURE_2D, texture[i]); gl.bindTexture(gl.TEXTURE_2D, texture[i]);
gl.texImage2D(gl.TEXTURE_2D, level, internalFormat, gl.texImage2D(gl.TEXTURE_2D, level, internalFormat,
srcFormat, srcType, image); srcFormat, srcType, image);
@ -77,13 +78,9 @@ function loadTexture(gl, url, i) {
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.activeTexture(gl.TEXTURE0+i);
gl.bindTexture(gl.TEXTURE_2D, texture[i]);
} }
}; };
image.src = url; image.src = url;
gl.activeTexture(gl.TEXTURE0+i);
gl.bindTexture(gl.TEXTURE_2D, texture[i]);
} }
function isPowerOf2(value) { function isPowerOf2(value) {
@ -93,7 +90,7 @@ function gl_start(canvas, vertexShader, fragmentShader) { // START WEB
setTimeout(function () { setTimeout(function () {
try { try {
canvas.gl = canvas.getContext('experimental-webgl'); // Make sure WebGl is supported. IT WOULD BE GREAT TO USE WEBGL2 INSTEAD. canvas.gl = canvas.getContext('webgl2'); // Make sure WebGl is supported. IT WOULD BE GREAT TO USE WEBGL2 INSTEAD.
} catch (e) { throw 'Sorry, your browser does not support WebGL.'; } } catch (e) { throw 'Sorry, your browser does not support WebGL.'; }
canvas.setShaders = function (vertexShader, fragmentShader) { // Add the vertex and fragment shaders: canvas.setShaders = function (vertexShader, fragmentShader) { // Add the vertex and fragment shaders:
@ -149,30 +146,12 @@ function gl_start(canvas, vertexShader, fragmentShader) { // START WEB
gl.useProgram(program); gl.useProgram(program);
gl.program = program; gl.program = program;
const ns = 2; const ns = 2;
errorMessage.innerHTML += gl.TEXTURE0 + ' '; for(let i = 0; i < ns; ++i){
errorMessage.innerHTML += gl.TEXTURE1; loadTexture(gl, './'+(i+1)+'.jpg', i); //Texture loading.
textures[i] = i;
// for(let i = 0; i < 2; ++i){ }
// let texture = loadTexture(gl, './'+(i+1)+'.jpg') //Texture loading.
// // Tell WebGL we want to affect texture unit 0
// if( i == 0 )
// gl.activeTexture(gl.TEXTURE0);
// else
// gl.activeTexture(gl.TEXTURE1);
// // Bind the texture to texture unit 0
// gl.bindTexture(gl.TEXTURE_2D, texture);
// // Tell the shader we bound the texture to texture unit 0
// textures[i] = i;
// }
loadTexture(gl, './1.jpg', 0); //Texture loading.
loadTexture(gl, './2.jpg', 1); //Texture loading.
gl.uniform1iv(gl.getUniformLocation(program, 'uSampler'), textures); gl.uniform1iv(gl.getUniformLocation(program, 'uSampler'), textures);
gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer()); // Create a square as a triangle strip gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer()); // Create a square as a triangle strip
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array( // consisting of two triangles. gl.bufferData(gl.ARRAY_BUFFER, new Float32Array( // consisting of two triangles.
[-1, 1, 0, 1, 1, 0, -1, -1, 0, 1, -1, 0]), gl.STATIC_DRAW); [-1, 1, 0, 1, 1, 0, -1, -1, 0, 1, -1, 0]), gl.STATIC_DRAW);

@ -1,130 +1,125 @@
uniform float uTime; // TIME, IN SECONDS uniform float uTime;// TIME, IN SECONDS
uniform int flags; uniform int flags;
varying vec3 vPos; // -1 < vPos.x < +1 //FLAGS 0-RT, 1-TEX, 2-
// -1 < vPos.y < +1 varying vec3 vPos;// -1 < vPos.x < +1
// vPos.z == 0 // -1 < vPos.y < +1
// vPos.z == 0
float fl = 3.0; float fl=3.;
const float pi = 3.14159265359; const float pi=3.14159265359;
const int n_ref=10;
const int ns = 2; const int ns=2;
vec4 Sph[ns]; vec4 Sph[ns];
uniform sampler2D uSampler[ns]; uniform sampler2D uSampler[ns];
vec3 Ambient [ns]; vec3 Ambient[ns];
vec3 Diffuse [ns]; vec3 Diffuse[ns];
vec4 Specular[ns]; vec4 Specular[ns];
// YOU MUST DEFINE A main() FUNCTION. bool getflag(int flag,int bit){
bool getflag(int flag, int bit){ float shifted = float(int(float(flag)/ pow(2.,float(bit))));
float shifted = float(flag) - pow(2., float(bit)); return fract(shifted/2.)>0.;
return fract(shifted / 2.) > 0.;
} }
float clampv(float val, float l, float h){ float clampv(float val,float l,float h){
return val < l? l:val > h? h:val; return val<l?l:val>h?h:val;
} }
void main() { void main(){
//////////////////////////////////////////////// ////////////////////////////////////////////////
// //
// HERE, FOR YOUR HOMEWORK, YOU CAN WRITE ANY // HERE, FOR YOUR HOMEWORK, YOU CAN WRITE ANY
// CODE YOU LIKDEFINE A COLOR FOR THIS FRAGMENT. // CODE YOU LIKDEFINE A COLOR FOR THIS FRAGMENT.
// LIGHT DIRECTION AND COLOR // LIGHT DIRECTION AND COLOR
vec3 LDir = vec3(.5,.5,.5); vec3 LDir=vec3(.5,.5,.5);
vec3 LCol = vec3(1.,1.,1.); vec3 LCol=vec3(1.,1.,1.);
// SPHERE // SPHERE
Sph[0] = vec4(.5*sin(uTime),0.,.5*cos(uTime), 0.2); Sph[0]=vec4(.5*sin(uTime),0.,.5*cos(uTime),.2);
Sph[1] = vec4(0.,0.,0., 0.2); Sph[1]=vec4(0.,0.,0.,.2);
// SURFACE REFLECTANCE PROPERTIES // SURFACE REFLECTANCE PROPERTIES
Ambient [0] = vec3(.1,.05,.05); // r,g,b Ambient[0]=vec3(.1,.05,.05);// r,g,b
Diffuse [0] = vec3(1.,.5,.5); // r,g,b Diffuse[0]=vec3(1.,.5,.5);// r,g,b
Specular[0] = vec4(1.,.5,.5, 10.); // r,g,b,power Specular[0]=vec4(1.,.5,.5,10.);// r,g,b,power
Ambient [1] = vec3(.05,.05,.1); // r,g,b Ambient[1]=vec3(.05,.05,.1);// r,g,b
Diffuse [1] = vec3(.5,.5,1.); // r,g,b Diffuse[1]=vec3(.5,.5,1.);// r,g,b
Specular[1] = vec4(1.,.5,.5, 20.); // r,g,b,power Specular[1]=vec4(1.,.5,.5,20.);// r,g,b,power
// INITIALIZE TO A BACKGROUND COLOR // INITIALIZE TO A BACKGROUND COLOR
vec3 color = vec3(.2, .3, .5); vec3 color=vec3(.2, .3, .5);
// COMPUTE THE RAY ORIGIN AND DIRECTION // COMPUTE THE RAY ORIGIN AND DIRECTION
float x=vPos.x;
float x = vPos.x; float y=vPos.y;
float y = vPos.y;
vec3 V=vec3(0.,0.,fl);
vec3 V = vec3(0.,0.,fl); vec3 W=normalize(vec3(x,y,-fl));
vec3 W = normalize(vec3(x, y, -fl)); // RAY TRACE TO ALL OBJECTS IN THE SCENE
// RAY TRACE TO ALL OBJECTS IN THE SCENE for(int j=0;j<n_ref;j++)
{
float tMin = 10000.0; float tMin=10000.;
for (int i = 0 ; i < ns ; i++) { int iMin = -1;
for(int i=0;i<ns;i++){
// SHIFT COORDINATES, SO THAT SPHERE IS AT (0,0,0) // SHIFT COORDINATES, SO THAT SPHERE IS AT (0,0,0)
vec3 Vp=V-Sph[i].xyz;
vec3 Vp = V - Sph[i].xyz; // SOLVE FOR QUADRATIC EQUATION IN t
float B=dot(W,Vp);
// SOLVE FOR QUADRATIC EQUATION IN t float C=dot(Vp,Vp)-Sph[i].w*Sph[i].w;
float D=B*B-C;
float B = dot(W, Vp); if(D>0.){
float C = dot(Vp, Vp) - Sph[i].w * Sph[i].w; float t=-B-sqrt(D);
float D = B*B - C; if(t > 0. && t < tMin){
if (D > 0.) { tMin = t;
float t = -B - sqrt(D); iMin = i;
}
// IF RAY HITS SPHERE }
}
if (t > 0. && t < tMin) { // IF RAY HITS SPHERE
float t = tMin;
float t = -B - sqrt(D); vec3 S=V+t*W;
for(int i = 0; i < ns; ++ i)
// IF RAY HITS SPHERE if(i == iMin)
vec3 S = V + t * W; {
if (t > 0. && t < tMin) { //*TEXTURE MAPPING
vec3 tex_sph = S - Sph[i].xyz; vec3 tex_sph=S-Sph[i].xyz;
// FIND SURFACE POINT AND NORMAL, DO SHADING float R=Sph[i].w;
float R = Sph[i].w; float tex_x=acos(abs(tex_sph.x)/sqrt(R*R-tex_sph.y*tex_sph.y));
float tex_x = acos(abs(tex_sph.x)/sqrt(R*R-tex_sph.y*tex_sph.y)); if(tex_sph.x>0.)
if(tex_sph.x > 0.) tex_x=pi-tex_x;
tex_x = pi - tex_x; tex_x=R*tex_x;
tex_x = R * tex_x; tex_x*=1.5708;//*Correct aspect ratio of texture 2:1 -> 2pir:2r
tex_x *= 1.5708;//*Correct aspect ratio of texture 2:1 -> 2pir:2r tex_x=tex_x+float(uTime)*R;
tex_x = tex_x + float(uTime)*R; float _2pir=2.*pi*R;
float _2pir = 2. * pi * R; float quo=float(int(tex_x/_2pir));
float quo = float(int(tex_x/_2pir)); tex_x=clampv((tex_x-quo*_2pir),0.,_2pir)/_2pir;
tex_x = clampv((tex_x - quo * _2pir), 0., _2pir) / _2pir; vec3 texture_color;
//*TEXTURE MAPPING if(!getflag(flags,0))
vec3 texture_color; texture_color=texture2D(uSampler[i],vec2(tex_x,((R-tex_sph.y)/(2.*R)))).xyz;
if(getflag(flags, 0))
texture_color = texture2D(uSampler[i], vec2(tex_x, ((R - tex_sph.y)/(2.*R)))).xyz; vec3 N=normalize(S-Sph[i].xyz);
vec3 VDir=normalize(V-Sph[i].xyz);
//*DIRECTIONS ARE NORMALIZED TO GET THE CORRECT PHONG LIGHTING
vec3 N = normalize(S - Sph[i].xyz); vec3 realLDir=normalize(LDir-S);
vec3 VDir = normalize(Vp); color=(
//*DIRECTIONS ARE NORMALIZED TO GET THE CORRECT PHONG LIGHTING Ambient[i]
vec3 realLDir = normalize(LDir - S); +Diffuse[i]*max(0.,dot(N,realLDir))*LCol
color = (Ambient[i] )*texture_color
+ Diffuse[i] * max(0.,dot(N,LDir)) * LCol) * texture_color // + SPECULAR COMPONENT GOES HERE
// + SPECULAR COMPONENT GOES HERE +Specular[i].xyz*pow(max(0.,dot(2.*dot(N,realLDir)*N-realLDir,VDir)),Specular[i].w)
+ Specular[i].xyz*pow(max(0., dot(2.*dot(N, LDir)*N - LDir, VDir)), Specular[i].w) ;
; break;
}
if(getflag(flags, 1))
tMin = t; break;
} }
} // APPLY GAMMA CORRECTION AND SET THE PIXEL COLOR.
} gl_FragColor=vec4(sqrt(color),1.);
}
// APPLY GAMMA CORRECTION AND SET THE PIXEL COLOR.
gl_FragColor = vec4(sqrt(color), 1.0);
}
}
Loading…
Cancel
Save