Hi,
I’m trying to adjust the opacity of a texture (loaded from a transparent PNG using SimpleTextured.j3md).
That is to say, doing something like setOpacity(0.5) would divide all the values of the PNG texture’s alpha channel by 2, making each pixel twice as transparent as what it was before (the final goal being to fade the object in or out). Is there any way to do this?
On a semi-related note (still about transparency), is it possible to add a black-and-white image an alpha map of another texture? Say I have a (partially transparent already, of course), and an equal-size grayscale image, and it’d multiply the alpha channel of each pixel by the whiteness of the corresponding pixel in the grayscale image. The same as setOpacity(float), but using pixel-specific values rather than a set number used for every pixel.
Thanks in advance.
The Lighting.j3md material supports alphamaps (m_AlphaMap).
I’m not sure if any materials currently support an overall alpha value, but it shouldn’t be hard to implement if you would like to try, we can help guide you. In the fragment shader it would be something like: color.rgb *= m_alpha;
Well, the overall alpha multiplier can be simulated by using (a lot of) different uniform-shade-of-gray textures, but that’s not very elegant.
Still, I really don’t know how to use the Lighting material. I’ve tried setting m_DiffuseMap to the texture I want it to use (and added a light to the scene), but the object looks completely black (It might be good to mention that my objects are within the guiNode; I’m trying to fade in or out GUI elements).
Make sure that the normals for your objects are pointing in the correct direction, if they aren’t the object will be black. Other than that, setting the diffuse texture should be sufficient.
It’s just a plain texture, do I really need a normal map for it? And how do I make sure the normals point in the correct direction? Make a full-white texture of the same size? I tried that and am getting inconsistent results (partially-visible textures, only when the objects is in certain areas). I’m guessing it’s also due to the now-required lights.
I’d just like plain textures with adjustable transparency for a HUD. Does that really require going the whole lighting + diffuse map + normal maps route?
You don’t need a normal map with the Lighting material. Just having diffuse and a light is enough.
You probably want to use the SimpleTextured material, but it needs an alpha map added into it to get the effects you want. So if you would like to try and tackle implementing that we can guide you in the right direction. It shouldnt be very difficult.
Well, I don’t really know how to go about it, so guess the “global alpha” thing should be done first as it is simpler.
Looking at this:
http://code.google.com/p/jmonkeyengine/source/browse/branches/jme3/src/core-data/Common/MatDefs/Misc/SimpleTextured.frag
There seems to already be a (commented) line that says
//color.rgb *= color.a;
I’m guessing you’d have to add “Float m_AphaValue” with a default value of 1.0f to the j3md file, then add “gl_FragColor.a *= m_AphaValue” in the .frag file (in the “#elif defined(SHOW_ALPHA)” section).
And then in code you’d call setFloat(“m_AphaValue”, 0.5f); to get 50% alpha.
I’m mostly guessing things here (and wouldn’t know how to actually compile that to be able to test it), so I might be totally wrong…
You will just need a Uniform variable passed into the fragment shader.
So first in the j3md file you will want to define the float:
Float m_GlobalAlpha // a global alpha value that will be applied to the entire texture
You will have to add it to the vertex shader too I believe so it gets passed on:
uniform float m_GlobalAlpha;
And then in the fragment shader add:
uniform float m_GlobalAlpha;
Then just setting the gl_FragColor.a by m_GlobalAlpha will change the alpha value that gets shown as the final result of that fragment.
m_GlobalAlpha should be initialized to 1.0, so if a person does not set that value, they will still see their texture.
The “#elif defined(SHOW_ALPHA)” section will use the alpha of the provided texture. You will want to leave that separate from your global alpha value and from your alpha map. So maybe add in an extra “Define” to the j3md file for SHOW_GLOBAL_ALPHA that is true if the m_GlobalAlpha value is passed in.
Here is a useful GLSL intro page for reference: http://www.lighthouse3d.com/opengl/glsl/index.php?intro
So, something like this:
(Note: I named the float variable “m_AlphaMultiplier” and named the boolean “m_UseAlphaMultiplier”).
AlphaTextured.j3md:
[java]MaterialDef Plain Texture {
MaterialParameters {
Texture2D m_ColorMap
Boolean m_YCoCg
Boolean m_LATC
Boolean m_Normalize
Boolean m_ShowAlpha
Float m_AlphaMultiplier
Boolean m_UseAlphaMultiplier
}
Technique {
VertexShader GLSL100: Common/MatDefs/Misc/AlphaTextured.vert
FragmentShader GLSL100: Common/MatDefs/Misc/AlphaTextured.frag
WorldParameters {
WorldViewProjectionMatrix
}
Defines {
DXT_YCOCG : m_YCoCg
NORMAL_LATC : m_LATC
NORMALIZE : m_Normalize
SHOW_ALPHA : m_ShowAlpha
USE_ALPHA_MULTIPLIER : m_UseAlphaMultiplier
}
}
Technique FixedFunc {
}
}[/java]
AlphaTextured.vert
[java]uniform mat4 g_WorldViewProjectionMatrix;
uniform float m_AlphaMultiplier;
attribute vec3 inPosition;
attribute vec2 inTexCoord;
varying vec2 texCoord;
void main(){
gl_Position = g_WorldViewProjectionMatrix * vec4(inPosition, 1.0);
texCoord = inTexCoord;
}[/java]
AlphaTextured.frag:
[java]#import “Common/ShaderLib/Texture.glsllib”
varying vec2 texCoord;
uniform sampler2D m_ColorMap;
uniform float m_AlphaMultiplier;
void main(){
#ifdef NORMAL_LATC
vec3 newNorm = vec3(texture2D(m_ColorMap, texCoord).ag, 0.0);
newNorm = Common_UnpackNormal(newNorm);
newNorm.b = sqrt(1.0 - (newNorm.x * newNorm.x) - (newNorm.y * newNorm.y));
newNorm = Common_PackNormal(newNorm);
gl_FragColor = vec4(newNorm, 1.0);
#elif defined(SHOW_ALPHA)
gl_FragColor = vec4(texture2D(m_ColorMap, texCoord).a);
#else
gl_FragColor = Texture_GetColor(m_ColorMap, texCoord);
#endif
#ifdef USE_ALPHA_MULTIPLIER
gl_FragColor.a *= m_AlphaMultiplier;
#endif
#ifdef NORMALIZE
gl_FragColor = vec4(normalize(gl_FragColor.xyz), gl_FragColor.a);
#endif
}[/java]
The thing is that I don’t know how to compile that into something actually usable with jMonkey. Do I just put these three files in my assets directories, or don’t I need to compile this first?
Well guess what, no it doesn’t. Just had to pop the files in the assets directory and it worked. I thought it had to be compiled because it looked a lot like C…
Anyway, thanks for the help! I should be able to write my own materials from now.
Cool, glad it’s working!
I figured get you pointed in the right direction and you will be able to run with it, which you have. So that’s great! We might have another person to generate materials for jme now