Unexpected transparency in alpha map from three.js RenderTarget - three.js

I’m using a RenderTarget in three.js/react-three-fiber to generate a simple alpha map using a Cylinder. The Cylinder uses a basic material with color white, which should be fully opaque in the alpha map, per the docs. However, when applied to a geometry, the area corresponding to white in the mask is not fully opaque, as shown in this example:
https://codesandbox.io/s/r3f-programmatic-alpha-map-f8lhi?file=%2Fsrc%2Findex.js
The scene setup is:
Red plane masked to a cylinder via the alpha mask - expected to be fully opaque
Behind that, a white box - it should not be visible at all from default camera position, but it is.
Does anyone have any idea why the white alpha mask leaves the Red plane with non-zero transparency (i.e. NOT fully opaque)? Thank you.

The explanation was provided by #drcmda here: there is a default tone mapping applied by react-three-fiber which results in the alpha map not being rendered pure white. To prevent that happening, disable tone mapping in the alpha map geometry material:
<Cylinder args={[1, 1, 1, 64]} position={[0, 0, 0]} rotation={[Math.PI / 2, 0, 0]}>
<meshBasicMaterial attach="material" color="white" toneMapped={false} />
</Cylinder>
i.e. in line 49 of the codesandbox linked in the question.

Related

Three.js material color is distorting the color of my texture

When I use THREE.MeshStandardMaterial with color 0xffffff, my textures are incredible washed out. The texture in this example is a solid #ff6600. The face below is the topic at hand.
When I set the underlying material color to 0xff6600 (the same as the texture), I get this result, which is exactly what I want!
This is a simplified example. What happens when half white, half orange?
In this case, I can have correct orange or correct white, but not both because the material color interferes!
What can be done to fix this?

SceneKit: Is it possible to cast an shadow on an Transparent Object?

i am trying to cast an shadow on an totally transparent plane in SceneKit on OSX. I am struggling with this problem since several hours and do not come to any solution.
My Purpose is to generate an Screenshot of several objects with an transparent background and just the shadow on an invisible Plane.
Do you have any suggestions for me how i can make this with apples SceneKit?
Do i have to program my own shader, can i make this work with shadermodifiers or can i use built in functionallity?
UPDATE:
I find an alternative solution for anyone who needs:
create a white plane under 3D model, note that the color of plane must be pure white.
set blend mode of plane's material to SCNBlendModeMultiply.
set light model of plane's material to SCNLightingModelLambert.
This works because any color multiply white color (1, ,1, 1) return itself And lambert light model will not take account of directional light, So the plane will always be background color which look like transparent. Another benefit of this solution is you don't need change light‘s shadow rendering mode.
For people who used to inspector of Xcode.
According to SceneKit: What's New.
First, add a plane under you model. Then prevent it from writing to colorBuffer.
Second, change your light model's shadow rendering mode to deferred. Notice that you must use light which can cast shadows.
Oily Guo, your solution works. Here the solution is in code:
Configuration of the light source:
light.shadowColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.4)
light.shadowMode = .deferred
And for the floor (ie. SCNFloor underneath your objects):
material.diffuse.contents = UIColor.white
material.colorBufferWriteMask = SCNColorMask(rawValue: 0)
I do not have an answer to your question, however I have a workaround:
Render your scene and keep the image in memory
Change all the materials in your object for pure black, no specular
Change the plane and the sky to a fully white material, lights to white
Render the scene to another image
On the second image, apply the CIColorInvertand CIMaskToAlpha Core Image filters
Using Core Image apply the Alpha Mask to the first render.
You'll get an image with a correct Alpha channel, and transparent shadows. You will need to tweak the materials and lights to get the results you want.
The shadow may become lighter on the edges, and the only way around that is rendering it as yet another image, and filling it with black after the Mask to Alpha step.

Fade Out OpenGL VBO with Colors but without Texture

I would like to fade out a VBO object in OpenGL ES. The VBO is drawn using RGBA format GL_UNSIGNED_BYTE like this:
glEnableClientState(GL_COLOR_ARRAY);
glColorPointer( 4, GL_UNSIGNED_BYTE, ....
I am fairly certain I should set up blending like this:
glEnable( GL_BLEND );
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
glColor4f( 1, 1, 1, alpha ); // I will be changing alpha from 1 to 0
But it doesn't fade, which makes sense, since I think the src alpha is coming from my VBO which is fixed.
So I thought maybe I should just pass 3 bytes to the driver keeping my VBO colors and then alpha will come from the glColor4f command.
glColorPointer( 3, GL_UNSIGNED_BYTE, ....
But this crashes for unclear reasons (iPad development with Xcode) which I am still trying to decipher. I would think all of my glColorPointer offsets would still be fine - I still have all 4 bytes (RGBA) in MyVertexObject so I don't think it's a padding issue - I do not change any offset values in the glColorPointer command, just changed the 4 to a 3.
If I disable GL_COLOR_ARRAY the fade works perfectly but now I've lost the colors and it's using the white color I set above.
So I'm stuck as it seems I can't control the alpha channel separately from the RGB colors. Is there another way to fade a VBO with colors? Thanks.
You can specify blend factors independently of the colors in your VBOs by using GL_CONSTANT_ALPHA as the blend function:
glBlendColor(0.0f, 0.0f, 0.0f, alpha);
glBlendFunc(GL_CONSTANT_ALPHA, GL_ONE_MINUS_CONSTANT_ALPHA);
This will use the alpha component specified in glBlendColor() for the blend function.

Twisted normals with the Three.js normal shader - r.58

I'm attempting to use the Three.js r.58 normal shader to make a displacement map. I have it displacing correctly, but the lighting doesn't seem to be respecting the post-displacement normals, even when I use computeTangents().
When I turn off the displacement, I see that the default normals are definitely funny. Here's a top view of a sphere, lit from the side (the white dot marks a pointLight):
And here's a demo page:
http://meetar.github.io/three.js-normal-map-0/index0.html
What's causing this? And is there documentation for the Three.js normal shader anywhere?
You are not passing in a normalMap, which is required. Try passing in a flat one.
ComputeTangents() can do strange things on vertices that have discontinuous UVs -- like at the north pole.
The code is the doucmentation. :-)
The "twisted" normals are the result of each vertex normal being evaluated as the RGB value (255, 255, 255), which corresponds to the tangent space XYZ coordinates (1.0, 1.0, 1.0). This seems to be the default behavior when a three.js normalmap material is used without passing a normal map. If you pass an all-white normal map, you'll see the same behavior.
To pass a normal map to the normalmap shader, add this line to your uniform declarations:
uniforms[ "tNormal" ].value = new THREE.ImageUtils.loadTexture( 'normalmap.png' );
To pass a "flat" normal map, make your "normalmap.png" solid (128, 128, 255) lavender, which normalizes to tangent-space coordinates (0.0, 0.0, 1.0).
For a great breakdown of normal maps including lots of examples, check out this link: http://wiki.polycount.com/NormalMap/

Transparent texture with OpenGL ES without using the alpha channel

Is it possible with OpenGL ES to texture a quad in such a way that all pixel (0,0,0) of the texture are not drawn while all the others are drawn? I have RGB888 images and the black color (0,0,0) is to be considered as completely transparent, while the other colors are completely opaque.
Thx
You could apply a fragment shader which sets the alpha color for pixels with RGB=(0,0,0) to 0. See here for details on writing a fragment shader.

Resources