Milestone 1:

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

@ -100,6 +100,13 @@ let vs = my_vertex_shader.innerHTML;
// START EVERYTHING.
gl_start(canvas1, vs, 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();
document.body.innerHTML = [''
@ -134,10 +141,7 @@ editor.setOptions({
});
editor.setAutoScrollEditorIntoView(true);
// 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 animating = true;
let ctrl = false;
@ -156,7 +160,7 @@ document.addEventListener('keydown',(e)=>{
else if(ctrl && e.code == 'KeyT')
{
mask = 0x1;
flags = flags&!mask | (!(flags&mask)?0:mask);
flags = flags&!mask | (!(flags&mask)?mask:0);
setUniform('1i', 'flags', flags);
}
else if (ctrl && e.code == 'KeyS')

@ -32,34 +32,35 @@ function getBlob(data) {
return new Blob([new Uint8Array(bytes)]);
}
let texture = [], gl, program;
let textures = [0, 1];
let textures = [];
let lock = false;
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)
{
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.texImage2D(gl.TEXTURE_2D, level, internalFormat,
width, height, border, srcFormat, srcType,
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 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();
image.onload = function () {
errorMessage.innerHTML += image.src + i;
gl.activeTexture(gl.TEXTURE0+i);
gl.bindTexture(gl.TEXTURE_2D, texture[i]);
gl.texImage2D(gl.TEXTURE_2D, level, internalFormat,
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_T, gl.CLAMP_TO_EDGE);
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;
gl.activeTexture(gl.TEXTURE0+i);
gl.bindTexture(gl.TEXTURE_2D, texture[i]);
}
function isPowerOf2(value) {
@ -93,7 +90,7 @@ function gl_start(canvas, vertexShader, fragmentShader) { // START WEB
setTimeout(function () {
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.'; }
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.program = program;
const ns = 2;
errorMessage.innerHTML += gl.TEXTURE0 + ' ';
errorMessage.innerHTML += gl.TEXTURE1;
// 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.
for(let i = 0; i < ns; ++i){
loadTexture(gl, './'+(i+1)+'.jpg', i); //Texture loading.
textures[i] = i;
}
gl.uniform1iv(gl.getUniformLocation(program, 'uSampler'), textures);
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.
[-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 int flags;
varying vec3 vPos; // -1 < vPos.x < +1
// -1 < vPos.y < +1
// vPos.z == 0
float fl = 3.0;
const float pi = 3.14159265359;
const int ns = 2;
vec4 Sph[ns];
uniform sampler2D uSampler[ns];
vec3 Ambient [ns];
vec3 Diffuse [ns];
vec4 Specular[ns];
// YOU MUST DEFINE A main() FUNCTION.
bool getflag(int flag, int bit){
float shifted = float(flag) - pow(2., float(bit));
return fract(shifted / 2.) > 0.;
uniform float uTime;// TIME, IN SECONDS
uniform int flags;
//FLAGS 0-RT, 1-TEX, 2-
varying vec3 vPos;// -1 < vPos.x < +1
// -1 < vPos.y < +1
// vPos.z == 0
float fl=3.;
const float pi=3.14159265359;
const int n_ref=10;
const int ns=2;
vec4 Sph[ns];
uniform sampler2D uSampler[ns];
vec3 Ambient[ns];
vec3 Diffuse[ns];
vec4 Specular[ns];
bool getflag(int flag,int bit){
float shifted = float(int(float(flag)/ pow(2.,float(bit))));
return fract(shifted/2.)>0.;
}
float clampv(float val, float l, float h){
return val < l? l:val > h? h:val;
float clampv(float val,float l,float h){
return val<l?l:val>h?h:val;
}
void main() {
////////////////////////////////////////////////
//
// HERE, FOR YOUR HOMEWORK, YOU CAN WRITE ANY
// CODE YOU LIKDEFINE A COLOR FOR THIS FRAGMENT.
// LIGHT DIRECTION AND COLOR
vec3 LDir = vec3(.5,.5,.5);
vec3 LCol = vec3(1.,1.,1.);
// SPHERE
Sph[0] = vec4(.5*sin(uTime),0.,.5*cos(uTime), 0.2);
Sph[1] = vec4(0.,0.,0., 0.2);
// SURFACE REFLECTANCE PROPERTIES
Ambient [0] = vec3(.1,.05,.05); // r,g,b
Diffuse [0] = vec3(1.,.5,.5); // r,g,b
Specular[0] = vec4(1.,.5,.5, 10.); // r,g,b,power
Ambient [1] = vec3(.05,.05,.1); // r,g,b
Diffuse [1] = vec3(.5,.5,1.); // r,g,b
Specular[1] = vec4(1.,.5,.5, 20.); // r,g,b,power
// INITIALIZE TO A BACKGROUND COLOR
vec3 color = vec3(.2, .3, .5);
// COMPUTE THE RAY ORIGIN AND DIRECTION
float x = vPos.x;
float y = vPos.y;
vec3 V = vec3(0.,0.,fl);
vec3 W = normalize(vec3(x, y, -fl));
// RAY TRACE TO ALL OBJECTS IN THE SCENE
float tMin = 10000.0;
for (int i = 0 ; i < ns ; i++) {
// SHIFT COORDINATES, SO THAT SPHERE IS AT (0,0,0)
vec3 Vp = V - Sph[i].xyz;
// SOLVE FOR QUADRATIC EQUATION IN t
float B = dot(W, Vp);
float C = dot(Vp, Vp) - Sph[i].w * Sph[i].w;
float D = B*B - C;
if (D > 0.) {
float t = -B - sqrt(D);
// IF RAY HITS SPHERE
if (t > 0. && t < tMin) {
float t = -B - sqrt(D);
// IF RAY HITS SPHERE
vec3 S = V + t * W;
if (t > 0. && t < tMin) {
vec3 tex_sph = S - Sph[i].xyz;
// FIND SURFACE POINT AND NORMAL, DO SHADING
float R = Sph[i].w;
float tex_x = acos(abs(tex_sph.x)/sqrt(R*R-tex_sph.y*tex_sph.y));
if(tex_sph.x > 0.)
tex_x = pi - tex_x;
tex_x = R * tex_x;
tex_x *= 1.5708;//*Correct aspect ratio of texture 2:1 -> 2pir:2r
tex_x = tex_x + float(uTime)*R;
float _2pir = 2. * pi * R;
float quo = float(int(tex_x/_2pir));
tex_x = clampv((tex_x - quo * _2pir), 0., _2pir) / _2pir;
//*TEXTURE MAPPING
vec3 texture_color;
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(Vp);
//*DIRECTIONS ARE NORMALIZED TO GET THE CORRECT PHONG LIGHTING
vec3 realLDir = normalize(LDir - S);
color = (Ambient[i]
+ Diffuse[i] * max(0.,dot(N,LDir)) * LCol) * texture_color
// + SPECULAR COMPONENT GOES HERE
+ Specular[i].xyz*pow(max(0., dot(2.*dot(N, LDir)*N - LDir, VDir)), Specular[i].w)
;
tMin = t;
}
}
}
// APPLY GAMMA CORRECTION AND SET THE PIXEL COLOR.
gl_FragColor = vec4(sqrt(color), 1.0);
}
}
void main(){
////////////////////////////////////////////////
//
// HERE, FOR YOUR HOMEWORK, YOU CAN WRITE ANY
// CODE YOU LIKDEFINE A COLOR FOR THIS FRAGMENT.
// LIGHT DIRECTION AND COLOR
vec3 LDir=vec3(.5,.5,.5);
vec3 LCol=vec3(1.,1.,1.);
// SPHERE
Sph[0]=vec4(.5*sin(uTime),0.,.5*cos(uTime),.2);
Sph[1]=vec4(0.,0.,0.,.2);
// SURFACE REFLECTANCE PROPERTIES
Ambient[0]=vec3(.1,.05,.05);// r,g,b
Diffuse[0]=vec3(1.,.5,.5);// r,g,b
Specular[0]=vec4(1.,.5,.5,10.);// r,g,b,power
Ambient[1]=vec3(.05,.05,.1);// r,g,b
Diffuse[1]=vec3(.5,.5,1.);// r,g,b
Specular[1]=vec4(1.,.5,.5,20.);// r,g,b,power
// INITIALIZE TO A BACKGROUND COLOR
vec3 color=vec3(.2, .3, .5);
// COMPUTE THE RAY ORIGIN AND DIRECTION
float x=vPos.x;
float y=vPos.y;
vec3 V=vec3(0.,0.,fl);
vec3 W=normalize(vec3(x,y,-fl));
// RAY TRACE TO ALL OBJECTS IN THE SCENE
for(int j=0;j<n_ref;j++)
{
float tMin=10000.;
int iMin = -1;
for(int i=0;i<ns;i++){
// SHIFT COORDINATES, SO THAT SPHERE IS AT (0,0,0)
vec3 Vp=V-Sph[i].xyz;
// SOLVE FOR QUADRATIC EQUATION IN t
float B=dot(W,Vp);
float C=dot(Vp,Vp)-Sph[i].w*Sph[i].w;
float D=B*B-C;
if(D>0.){
float t=-B-sqrt(D);
if(t > 0. && t < tMin){
tMin = t;
iMin = i;
}
}
}
// IF RAY HITS SPHERE
float t = tMin;
vec3 S=V+t*W;
for(int i = 0; i < ns; ++ i)
if(i == iMin)
{
//*TEXTURE MAPPING
vec3 tex_sph=S-Sph[i].xyz;
float R=Sph[i].w;
float tex_x=acos(abs(tex_sph.x)/sqrt(R*R-tex_sph.y*tex_sph.y));
if(tex_sph.x>0.)
tex_x=pi-tex_x;
tex_x=R*tex_x;
tex_x*=1.5708;//*Correct aspect ratio of texture 2:1 -> 2pir:2r
tex_x=tex_x+float(uTime)*R;
float _2pir=2.*pi*R;
float quo=float(int(tex_x/_2pir));
tex_x=clampv((tex_x-quo*_2pir),0.,_2pir)/_2pir;
vec3 texture_color;
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 realLDir=normalize(LDir-S);
color=(
Ambient[i]
+Diffuse[i]*max(0.,dot(N,realLDir))*LCol
)*texture_color
// + SPECULAR COMPONENT GOES HERE
+Specular[i].xyz*pow(max(0.,dot(2.*dot(N,realLDir)*N-realLDir,VDir)),Specular[i].w)
;
break;
}
if(getflag(flags, 1))
break;
}
// APPLY GAMMA CORRECTION AND SET THE PIXEL COLOR.
gl_FragColor=vec4(sqrt(color),1.);
}
Loading…
Cancel
Save