Simplest shader toy output in HTML canvas - html5-canvas

I have made this simple shader toy thing: https://www.shadertoy.com/view/DsfSzM#
What is the simplest way to use the shader toy output (HSLS) to render the same thing in the preview in my own <canvas> element. Something like:
const canvas = document.querySelector("#myCanvas");
const webGLContext = canvas.getContext("webgl");
// Want
webGLContext.render("float4 vec4_ctor(float3 x0, float x1) ...");
I don't want to do anything other than just represent the same thing rendered on shader toy. Don't want to use heavy libraries. The shader animates over time (but doesn't take any other input), guessing that it is an input handled on the JS side?

Related

three.js - how to use alphatest value inside ShaderMaterial and fragmentShader

Thansks to #Mugen87, I managed to create a dynamic mask on my scene using a post processing method : https://jsfiddle.net/40gef6sz/ (if you move the camera you will see the cube disappear behind and invisible circle, made with this image : https://i.imgur.com/sJwKYvZ.jpg)
I would like to add some effects on my mask using a fragment shader script. On this fiddle you can see my texture moving (I replaced a THREE.MeshBasicMaterial with a THREE.ShaderMaterial) : https://jsfiddle.net/grc_michael/ghmf5sdo/
When I combine this new material with the post processing method, I can't reach the same result than the first jsfiddle. I don't know where to add my #define ALPHATEST value inside my fragment shader.
You can see the result here : https://jsfiddle.net/grc_michael/82bkLn96/
I think I'm quite close the expected result. Does anyone know where to add the ALPHATEST value properly inside my fragment shader ? Thank you
Here us the original, updated fiddle with your custom shader material: https://jsfiddle.net/k2c5upfo/1/
When using an image as an alpha map, you can sample it in the same way like built-in materials. Meaning the alpha test looks like so:
if (texture2D(texture1,xy).g < 0.5) discard;

Render single Object / Mesh immediatly into a renderTarget

I need to render a single specific mesh from a scene into a texture using a THREE.WebGLRenderTarget. I already achieved that during the rendering of the scene, all other meshes, except this one, are being ignored. So, I basically achieved my goal. The thing i hate is, that there is still a lot of unnecessary work going on for my whole scene graph, during the render process of the scene. I need to render this texture every frame, so with my current method i get extrem fps drop downs. (There are lots of meshes in the whole scene graph).
So what i found was the function "renderBufferImmediate" from the THREE.WebGLRenderer. (Link to the renderer source code here) My pseudo code to achieve my goal would look like this:
var mesh = some_Mesh;
var renderer = some_WebGLRenderer;
var renderTarget = some_WebGLRenderTarget;
renderer.setRenderTarget(renderTarget);
var materialProperties = renderer.properties.get(mesh.material);
var program = materialProperties.program;
renderer.renderBufferImmediate(mesh, program, mesh.material);
var texture = renderTarget.texture;
The renderBufferImmediate function takes an instance of an THREE.Object3D, a WebGLShaderProgram and a THREE.Material. Problem i see here: The implementation of this function tries to lookup properties of the Object3D which, afaik doesn't exist. (Like "hasPositions" or "hasNormals"). In short: my approach doesn't work.
I would be grateful if someone could tell me if i can use this function for my purpose (Meaning i am currently using it wrong) or if there is another solution for my problem.
Thanks in advance.

Animate CC Canvas And Masking

I am wondering how I would be able to use animated shapes inside a movieclip that would be acting as a mask?
In my Animate CC canvas file I have an instance (stripeMask) that should mask the below instance called mapAnim.
stripeMask contains shapes that are animating in.
So when the function maskIn is called, the playhead should move to the first frame inside the stripeMask clip (the one after frame 0) and animate the mask like so:
function maskIn(){
//maskAnimation to reveal image below
stripeMask.gotoAndPlay(1);
}
I love AnimateCC and it works great, but the need for creating more complex and animated masks is there and it's not easy to achieve unless I am missing something here.
Thanks!
Currently you can only use a Shape as a mask, not a Container or MovieClip.
If you want to do something more complex, you can use something like AlphaMaskFilter, but it has to be cached, and then updated every time the mask OR the content updates:
something.filters = [new createjs.AlphaMaskFilter(stripeMask)];
something cache(0,0,w,h);
// On Change
something.updateCache(); // Re-caches
The source of the AlphaMaskFilter must be an image, so you can either point to a Bitmap image, or a cacheCanvas of a mask clip you have also cached. Note that if the mask changes, the cache has to be updated as well.
This is admittedly not a fantastic solution, and we are working on other options.

Changing scale of Three.js object after it is loaded

I am developing an augmented reality project using Three.js and aruco-js. I made my code so that all my 3D Objects are added to the scene (empty) at the beginning but the data gets initially loaded on marker detection.
Now I want to create an interface for changing the objects appearance, starting with the possibility of scaling an object.
So I created an updateObject() function to set the new values like this:
function updateObject(object, rotation, translation)
{
...
...
...
// first method
object.scale.x = 200;
object.scale.y = 200;
object.scale.z = 200;
// second attempt
object.scale.set(300, 300, 300);
};
I tried both of the methods shown above to set the scale of my object but it has no effect to the rendered images I get. The interesting thing is that the values of the objects in my scene3d DOM object are the values I set in my function. But why doesn't it have any impact on the output?
I'm not very familiar with 3d programming in WebGL or Three.js, so if you could give me any hint where the problem might has it's origin I would really appreciate an answer.
FIX:
I took a closer look to the 3D objects I was loading and discovered that they have a children called "mesh" inside another children. By trying to change the scale of only the mesh I found out that it works this way. But I think it looks very ugly:
scene3d.children[visibleModels[0][0]+3].children[0].children[0].scale.set(2, 2, 2);
//visibleModels is a list of the markers/models that should be loaded
This is only a test for one single object to change but at least I found a way to solve this. Is this an ordinary way to change the scale of objects? If you have a better solution or anything to add feel free to contribute.
You could also try to scale the object by changing its matrix using the THREE.Matrix4.makeScale method instead:
object.matrix.makeScale( xScale, yScale, zScale );
Or the even simpler THREE.Matrix4.scale method:
object.matrix.scale( scale );

how to reset opengl modelview matrix?

Although I am using opengl es 1.1,but I want to try to work with my own matrix stuff,
I built a fps camera matrix function called : fpsmatrixupdate();
then I call it like this:
fpsmatrixupdate(); //this function generated a matrix called mat
drawbox(min,max)
everything works great,until I am trying to draw another box:
fpsmatrixupdate(); //this function generated a matrix called mat
drawbox(min,max);
glLoadIdentity(); // I tried to call this before drawbox2 but box2 doesn't show
drawbox2(min,max);
questions: why this works?
fpsmatrixupdate(); //this function generated a matrix called mat
drawbox(min,max);
glLoadMatrixf(mat); // mat is fps camera update function generated matrix,
drawbox2(min,max);
if I want to draw 200 boxes with different location, do I have to call glLoadMatrixf(mat) 200 times? if I don't call glLoadMatrixf(mat) to reset matrix ,the second box's transform is based on first box..
if anybody want to see the code, they are almost 99% copied from this demo:
http://www.codesampler.com/oglsrc/oglsrc_5.htm#ogl_fps_controls
Yes, if you want to base your objects' placement on a per-object transformation, you've to do a glLoadMatrix each time. It makes sense to calculate the transformation matrices once and store them in each object's scene data for easy access.

Resources