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,19 +32,9 @@ 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) {
if (texture[i] == null)
{
texture[i] = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture[i]);
}
// Because images have to be downloaded over the internet
// they might take a moment until they are ready.
// Until then put a single pixel in the texture so we can
// use it immediately. When the image has finished downloading
// we'll update the texture with the contents of the image.
const level = 0; const level = 0;
const internalFormat = gl.RGBA; const internalFormat = gl.RGBA;
const width = 1; const width = 1;
@ -52,14 +42,25 @@ function loadTexture(gl, url, i) {
const border = 0; const border = 0;
const srcFormat = gl.RGBA; const srcFormat = gl.RGBA;
const srcType = gl.UNSIGNED_BYTE; const srcType = gl.UNSIGNED_BYTE;
if (texture[i] == null)
{
texture[i] = gl.createTexture();
const pixel = new Uint8Array([0, 0, 255, 255]); // opaque blue const pixel = new Uint8Array([0, 0, 255, 255]); // opaque blue
gl.activeTexture(gl.TEXTURE0+i);
gl.bindTexture(gl.TEXTURE_2D, texture[i]);
gl.texImage2D(gl.TEXTURE_2D, level, internalFormat, gl.texImage2D(gl.TEXTURE_2D, level, internalFormat,
width, height, border, srcFormat, srcType, width, height, border, srcFormat, srcType,
pixel); pixel);
}
// Because images have to be downloaded over the internet
// they might take a moment until they are ready.
// Until then put a single pixel in the texture so we can
// use it immediately. When the image has finished downloading
// we'll update the texture with the contents of the image.
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,14 +1,14 @@
uniform float uTime;// TIME, IN SECONDS uniform float uTime;// TIME, IN SECONDS
uniform int flags; uniform int flags;
//FLAGS 0-RT, 1-TEX, 2-
varying vec3 vPos;// -1 < vPos.x < +1 varying vec3 vPos;// -1 < vPos.x < +1
// -1 < vPos.y < +1 // -1 < vPos.y < +1
// vPos.z == 0 // vPos.z == 0
float fl=3.;
float fl = 3.0;
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];
@ -16,9 +16,8 @@
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(flag) - pow(2., float(bit)); float shifted = float(int(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){
@ -38,8 +37,8 @@ float clampv(float val, float l, float h){
// 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
@ -56,41 +55,40 @@ float clampv(float val, float l, float h){
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
float tMin = 10000.0; for(int j=0;j<n_ref;j++)
{
float tMin=10000.;
int iMin = -1;
for(int i=0;i<ns;i++){ 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 // SOLVE FOR QUADRATIC EQUATION IN t
float B=dot(W,Vp); float B=dot(W,Vp);
float C=dot(Vp,Vp)-Sph[i].w*Sph[i].w; float C=dot(Vp,Vp)-Sph[i].w*Sph[i].w;
float D=B*B-C; float D=B*B-C;
if(D>0.){ if(D>0.){
float t=-B-sqrt(D); float t=-B-sqrt(D);
// IF RAY HITS SPHERE
if(t > 0. && t < tMin){ if(t > 0. && t < tMin){
tMin = t;
float t = -B - sqrt(D); iMin = i;
}
}
}
// IF RAY HITS SPHERE // IF RAY HITS SPHERE
float t = tMin;
vec3 S=V+t*W; vec3 S=V+t*W;
if (t > 0. && t < tMin) { for(int i = 0; i < ns; ++ i)
if(i == iMin)
{
//*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.)
@ -101,30 +99,27 @@ float clampv(float val, float l, float h){
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;
//*TEXTURE MAPPING
vec3 texture_color; vec3 texture_color;
if(getflag(flags, 0)) if(!getflag(flags,0))
texture_color=texture2D(uSampler[i],vec2(tex_x,((R-tex_sph.y)/(2.*R)))).xyz; texture_color=texture2D(uSampler[i],vec2(tex_x,((R-tex_sph.y)/(2.*R)))).xyz;
vec3 N=normalize(S-Sph[i].xyz); vec3 N=normalize(S-Sph[i].xyz);
vec3 VDir = normalize(Vp); vec3 VDir=normalize(V-Sph[i].xyz);
//*DIRECTIONS ARE NORMALIZED TO GET THE CORRECT PHONG LIGHTING //*DIRECTIONS ARE NORMALIZED TO GET THE CORRECT PHONG LIGHTING
vec3 realLDir=normalize(LDir-S); vec3 realLDir=normalize(LDir-S);
color = (Ambient[i] color=(
+ Diffuse[i] * max(0.,dot(N,LDir)) * LCol) * texture_color Ambient[i]
+Diffuse[i]*max(0.,dot(N,realLDir))*LCol
)*texture_color
// + SPECULAR COMPONENT GOES HERE // + SPECULAR COMPONENT GOES HERE
+ Specular[i].xyz*pow(max(0., dot(2.*dot(N, LDir)*N - LDir, VDir)), Specular[i].w) +Specular[i].xyz*pow(max(0.,dot(2.*dot(N,realLDir)*N-realLDir,VDir)),Specular[i].w)
; ;
break;
tMin = t;
} }
if(getflag(flags, 1))
break;
} }
}
// APPLY GAMMA CORRECTION AND SET THE PIXEL COLOR. // APPLY GAMMA CORRECTION AND SET THE PIXEL COLOR.
gl_FragColor=vec4(sqrt(color),1.);
gl_FragColor = vec4(sqrt(color), 1.0);
}
} }
Loading…
Cancel
Save