I write an application with WebGL. In my fragment shader I set constant color to fragment but in my canvas I actually get a slightly different color. For example I write this code to my fragment shader:
precision mediump float;
void main(void){
gl_FragColor = vec4(0.0, 0.0, 1.0, 1.0);
}
In my canvas i see color #0005FA which is not what i want.
On the other hand when I set output color for example to vec4(1.0) then in my canvas I get correct color #FFFFFF.
I got this problem when using Google chrome. In Firefox colors are just fine. I use Debian OS, maybe it is related with this problem.
The difference in colors is not noticable but ruins my debbuging. I cannot properly read values. Does anybody know how to solve this?
Related
I am using GL 2.0 (in order to display pictures that are not power of 2), and I am trying to simply render a mesh (that displays some triangles).
When using GL 1.0, I didn't have any problem, but now, I have to pass a ShaderProgram object as a parameter.
How can I make it work like it would in GL 1.0?
Should I make a shader that simply does nothing?
You have to use a vertex shader to convert world space coordinates into screen space coordinates. And you need a pixel shader to look up texture coordinates for each rendered pixel of your quad.
Look at the shaders that Libgdx uses for its SpriteBatch, they are pretty minimal texture-a-quad shaders. You can literally use SpriteBatch.createDefaultShader() to get them or just use them as inspiration for your own shaders.
The libgdx wiki page on shaders already contains an example code for a simple shader:
https://github.com/libgdx/libgdx/wiki/Shaders
I assume it's basically the same as the createDefaultShader() as in P.T.'s answer...
Hope it helps...
I'm drawing a simple square in stage3D, but the quality of the numbers and the edges in the picture is not as high as it should be:
Here's the example with the (little) source code, I've put the most in one file.
http://users.telenet.be/fusion/SquareQuality/
http://users.telenet.be/fusion/SquareQuality/srcview/
I'm using mipmapping, in my shader I use "<2d, miplinear, repeat>", the texture is 256x256 jpg (bigger than on the image), also tried a png, tried "mipnearest" and tried without mipmapping. Anti-alias 4, but 10 or more doesn't help at all...
Any ideas?
Greetings,
Thomas
Are you using antialiasing for backBuffer?
// Listen for when the Context3D is created for it
stage3D.addEventListener(Event.CONTEXT3D_CREATE, onContext3DCreated);
function onContext3DCreated(ev:Event): void
{
var context3D:Context3D = stage3D.context3D;
// Setup the back buffer for the context
context3D.configureBackBuffer(stage.stageWidth, stage.stageHeight,
0, // no antialiasing (values 2-16 for antialiasing)
true);
}
I think that the size of your resource texture is too high. The GPU renders your scene pixel by pixel in the fragment shader. When it renders a pixel of your texture, the fragment shader gets a varying that represents the texture UV. The GPU simply takes the color of the pixel on that UV coordinate of your texture.
Now, when your texture size is too high, you will lose information because two neighboring pixels on the screen will correspond with non-neighboring pixels on the texture resource. For example: if you draw a texture 10 times smaller than the resource, you will get something like this (were each character corresponds with a pixel, in one dimension):
Texture: 0123456789ABCDEFGHIJKLM
Screen: 0AK
I'VE FOUND IT!!!
I went to the Starling forum and found an answer from Daniel from Starling:
"If you're using TRILINEAR, you're already using the best quality available. One additional thing you could try is to set the "antialiasing" value of Starling to a high value, e.g. 16, and see if that helps."
So I came across this article that said trilinear is only used when you put the argument "linear" in your fragment shader, in my example program:
"tex ft0, v0, fs0 <2d, linear, miplinear, repeat>".
Greetings,
Thomas
I've been trying to create a multiviewport webgl application.
I got everything rendering quite nice using viewport+scissor for each view.
But now I would like to improve rendering and just render the view which is updated, so skip overdrawing.
I've made a little demo showing the idea: http://kile.stravaganza.org/lab/js/scissor/
As I understand scissor it's suposse that it will just render the current scissor box and keep the rest of the canvas untouched. But it seems that it just keeps clearing the whole canvas on each frame, no matter what I tried :(
This is the rendering code (The last view it's supossed to be rendered just once and keep it on each frame):
function drawScene()
{
gl.clearColor(1.0, 0.0, 0.0, 0.0);
gl.scissor(0,0,200,200);
gl.viewport(0,0,200,200);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
drawFigures();
gl.clearColor(0.0, 1.0, 0.0, 0.0);
gl.scissor(200,0,200,200);
gl.viewport(200,0,200,200);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
drawFigures();
gl.clearColor(0.0, 0.0, 1.0, 0.0);
gl.scissor(200,200,200,200);
gl.viewport(200,200,200,200);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
drawFigures();
// Render just once
if (first)
{
gl.clearColor(1.0, 1.0, 0.0, 0.0);
gl.scissor(0,200,200,200);
gl.viewport(0,200,200,200);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
drawFigures();
first=false;
}
}
Any idea how could I achieve this effect?
Thank you very much in advance
You can use the preserveDrawingBuffer attribute:
gl = canvas.getContext("experimental-webgl", { preserveDrawingBuffer: true });
It isn't recommended to use this in production. The WebGL specifications states:
While it is sometimes desirable to preserve the drawing buffer, it can
cause significant performance loss on some platforms. Whenever
possible this flag should remain false and other techniques used.
Techniques like synchronous drawing buffer access (e.g., calling
readPixels or toDataURL in the same function that renders to the
drawing buffer) can be used to get the contents of the drawing buffer.
If the author needs to render to the same drawing buffer over a series
of calls, a Framebuffer Object can be used.
This SO question contains also relevant information regarding preserveDrawingBuffer: When WebGL decide to update the display?
I am making a drawing application w/ GWT (2.2.0) canvas.
The problem that I'm having is that I can't set the opacity of the color.
HTML5Canvas supports the alpha channel. However through GWT it passes whatever string into a CssColor which drops the alpha.
Meaning in JS this works (I think):
context.strokeStyle = "rgba(0,0,0,0.5)";
But in GWT this doesn't (ignores alpha)
context.setStrokeStyle("rgba(0,0,0,0.5)");
because it transfers to
setStrokeStyle(CssColor.make("rgba(0,0,0,0.5)"))
And CssColor doesn't support transparency.
Any suggestions on how to go around this issue.
P.S. This is a very needed feature to be able to, say have an eraser and a highlighter.
EDIT: Square erasers can be done using context.clearRect(...), but that's not what I'm going for.
I found for you a nice example here. I hope it will help you!
I have a series of movieclips containing both bitmaps and text.
After applying some 3d transformations and moving in 3d space, my text and bitmaps are slightly blurred. This is AFTER I reset all the 3d coordinates (ie z=0, rotationX=0, rotationY=0)
Has anyone else encountered this? Is there a solution to get my crisp text and bitmaps back?
this is a very interesting error.
the blur that appears is actually improper anti-aliasing, or smoothing that is usually solved by rendering the font with fine colors along the edges. in this case, it is in fact caused by 3D transformations and can be solved by nullifying the matrix3D after the animation:
myTextContainer.transform.matrix3D = null;
you could also write:
myTextContainer.transform.matrix = new Matrix();
but with this approach you'll have to import flash.geom.Matrix.
both options will also reset to zero the x and y coordinates, and possibly other important settings of the animated display object, so you'll also have to assign those values to variables and reapply them after nullifying the transform matrix.
it seems that once a font is transformed, it loses this fine color tinting. non transformed fonts have these color details while transformed fonts become completely desaturated.
attached is a zoomed in detail of 12 point font which exhibits this loss of color detail. the top string has no 3D transformation while the bottom string was animated onto the stage via rotationY.
here is the same image saturated to 90% to show the colors more clearly:
these color details are easier to see on grey text.
i believe this error has been present since Flash Player 9 / AVM2 was first introduced. additionally, the fine color detail around the properly rendered font was much more saturated in early versions of the Flash player, which, in my opinion, made the fonts look much better - although the difference could be considered negligible by non perfectionists unlike myself.
You need to make sure you set the matrix3D property to null on any objects that you've applied 3D transformation to.
Looking up another post on 3d issues and came across the solution.
You need to remove all 3d transformations by applying a new transfrom.matrix
var tempMatrix:Matrix = new Matrix();
this.transform.matrix = tempMatrix;
An Even better answer is to use this fix. It's one I used to use all the time.
/**
* Fixes the slight distortion that occurs when an object has a 3D transform associated with it.
* #param di:DisplayObject The DisplayOjbect to fix.
*/
public function fix3DBlur(di:DisplayObject):void {
di.scaleX = di.width / (di.width - 1);
di.scaleY = di.height / (di.height - 1);
}
This function sets a slightly offset scaleX and scaleY. It seems weird, but they when you make 3d adjustments to the object using any 3d property it keep it from looking blurry. You can always remove the 3DTransform, but sometimes you need it to stay in place.
I place this function on a Utilities3D class I have.