Setting the opacity of an already partially transparent texture

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.

1 Like

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

1 Like

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 :wink: