My Personal Portfolio Website | 3D Room

Finally, my Three.js portfolio is live! !:rocket:

Explore my skills in GLSL, Three.js, and game programming. For now, only available on PC.

Live Demo: http://joanramosrefusta.com
Source Code: https://github.com/jrefusta/joan-portfolio

Please share any thought/comment. Any feedback is welcomed!

Joan.

4 Likes

Looks really nice. I bit heavy for my machine (or the damping is too big). What I liked most is:

  • I managed to play some Tetris
  • the white board is a draft model of the room (and I was able to draw on it)
  • the Rubik’s cube is gameable (sadly, the chess is not)

In case you are interested is some other observations, here are a few. Do not worry, most visitor of your site will not notice them:

  1. You may need some antialiasing or anisotropic filtering
  2. the shadow of the chair and the shadow on the chair do not change while the chair spins
  3. the coffee vapour is flat (especially where it goes out of the coffee)
  4. sometime the Rubik’s cube interactivity is strange. When I move the cursor from the top red to the left white square (the yellow arrow), the left side is rotated (the green arrow)
  5. there is unexpected dent of the monitor’s shadow
  6. at close-up, the PS logo has a lot of Z-fighting – here are two snapshot
  7. the topology of the dumbbell ‘rapes’ my mind – see the vertices of the outermost disk – should they match or not match?
  8. from the view point of a cockroach, the top layer of the carpet is scary (it looks like thousands of small disks – I know, the snapshot is not very representative, but if this is the case, you have a lot of geometry that is barely noticeable, but adds weight to the model)

1 Like

Wow, thank you so much for your incredible and deep testing of my portfolio! Really appreciate it!

I am happy to read someone who has spend time on my work and understands the basis of it. Will try to answer each of yout bulletpoints!

1. You may need some antialiasing or anisotropic filtering

I already have antialiasing and anisotropic filtering, in fact, per each texture I am getting the max anisotropic from the renderer like this:

this.maxAnisotropy = this.renderer.capabilities.getMaxAnisotropy();

And applying it for each texture.

But what I am using at the 3 screens from my portfolio (left monitor, right monitor and arcade screen) are not textures, but an iframe from CSS3DObject.

const container = document.createElement("div");
container.style.width = this.screenMonitorSize.width + "px";
container.style.height = this.screenMonitorSize.height + "px";
const iframe = document.createElement("iframe");

iframe.src = LEFT_MONITOR_IFRAME_SRC;
iframe.style.width = this.screenMonitorSize.width + "px";
iframe.style.height = this.screenMonitorSize.height + "px";
iframe.style.padding = MONITOR_IFRAME_PADDING;

iframe.style.transparent = true;
iframe.id = "left-monitor-screen";
iframe.style.boxSizing = "border-box";
iframe.style.background = "black";
container.appendChild(iframe);

const css3dobject = new CSS3DObject(container);

css3dobject.position.copy(LEFT_MONITOR_CSS_OBJECT_POSITION);
css3dobject.scale.copy(LEFT_MONITOR_CSS_OBJECT_SCALE);
this.cssLeftMonitorScene.add(css3dobject);

const material = new MeshLambertMaterial({
  color: "black",
  opacity: 0,
  transparent: true,
  blending: NoBlending,
});

const geometry = new PlaneGeometry(
  this.screenMonitorSize.width,
  this.screenMonitorSize.height
);

const screen = new Mesh(geometry, material);
screen.position.copy(css3dobject.position);
screen.rotation.copy(css3dobject.rotation);
screen.scale.copy(css3dobject.scale);
screen.name = "leftMonitorScreen";
this.model.mesh.add(screen);

This part of code is from: joan-portfolio/src/Experience/LeftMonitorScreen.js at 5aaaee9653194f65628f9fe4f296b22c80b3a976 · jrefusta/joan-portfolio · GitHub
Thus, i’s not possible for me to add some antialias/anisotropic there, since it is not exactly a texture. I am not sure If there’s something I could do there.

Please let me know If you know some technique that I could apply in my case! :slight_smile:

2. the shadow of the chair and the shadow on the chair do not change while the chair spins

Yeah, this is because the entire scene is baked, that means that every light/shadow is captured as static. Using that technique allows me to have a more realistic shadow representation and less computation use since the lightmap is not calculated.

I am aware that the chair’s movement doesn’t match with the shadow’s casting, but I think it gives it a livelier touch to spin like this, don’t you?

3. the coffee vapour is flat (especially where it goes out of the coffee)

Yes! I know, it is totally flat, in fact, I am only using 4 vertices to represent a coffee steam, since it is a ShaderMaterial in a plane, which is really cool.

The point of using this kind of implementation is for the visitor to appreciate also my shader work, implementing very low cost techniques to reproduce awesome behaviors.

But I get it, If you have a closer look into that, it is not very realistic. Another alternative would be using some volumetric fog for that, which implies more computational cost.

4. sometime the Rubik’s cube interactivity is strange. When I move the cursor from the top red to the left white square (the yellow arrow), the left side is rotated (the green arrow)

Yeah, this is because of the controls that I developed.

So, once the user does a mousedown, I get the initial position of the screen that the user has clicked, and after dragging, and mouseup, I get the second point of the screen.

If the horizontal distance is greater than the vertical distance, I do a move, otherwise, another, and also depending on the sign, I do it with a positive orientation, or a negative one.

It could be a bit tricky to understand and probably not the best controls for this kind of “game”, but was a simple solution for every single case, think that every single little cube you see on the screen has 4 diferent moves, so I tried my best to afford all of them.

5. there is unexpected dent of the monitor’s shadow

Since shadow is made by Blender’s Cycles, I assume this little dent represents the separation of the two monitors, which makes a lot of sense for me since there’s some light coming throw the window.

6. at close-up, the PS logo has a lot of Z-fighting – here are two snapshot
7. the topology of the dumbbell ‘rapes’ my mind – see the vertices of the outermost disk – should they match or not match?

Yep, both are totally issues from my side, I could fix it I think I will take a closer look once I have some time, thanks for letting me know!

8. from the view point of a cockroach, the top layer of the carpet is scary (it looks like thousands of small disks – I know, the snapshot is not very representative, but if this is the case, you have a lot of geometry that is barely noticeable, but adds weight to the model)

I love this one! I let it on purpose, for the ones more curious (As you :slight_smile: ), in order to show that I am able to reproduce this Shell Texturing in Three js.

The carpet is not a 3D model per se, is a group of planes with a shader material that creates this cool effect. I am performing a very cool technique called shell texturing and you can have more information here: https://www.youtube.com/watch?v=9dr-tRQzij4&ab_channel=Acerola

Is basically a very common technique used in videogames (for example, to create fur or grass). Shell texturing is used, for example, at Dark Souls for the Sif’s fur:

Or in Viva Piñata’s grass:

image

I see you consider that I have a lot of geometry there, but the true is that I am only using 32 planes that have only 4 vertices per plane (32 x 4 vertices) to represent my carpet.

Every single carpet is only painted the parts I need to create this little threads, the other fragments are discarded.

If you still interested in how I get this effect you can have a look at my source code for that shader:

That is added to each ShaderMaterial to each plane that represents the carpet.

Again, thank you so much for your feedback Pavel, I strongly appreciate it :slight_smile:

Hope your questions are being solved now, but let me know If you have some additional comments.

Best,
Joan.

2 Likes