How render D3DFMT_A8 texture as colour? - graphics

Is it possible to render D3DFMT_A8 texture with some colour? Like this:
D3DXCreateTexture (pDevice, 128, 128, 0, D3DFMT_A8, D3DPOOL_MANAGED, &pTexture)
...
pSprite->Draw (pTexture, NULL, NULL , NULL, 0, pos, 0xffff0000); // red
Thanks!

Firstly, not all hardware supports D3DFMT_A8.
Now assuming that ID3DXSprite doesn't take over too much of the pipeline then its a simple matter of writing a pixel shader as follows:
sampler2D input : register(s0);
float4 pixelShader(float2 uv : TEXCOORD) : COLOR
{
return tex2D( input , uv.xy).aaaa;
}
The shader simply reads in the value in the texture and swizzles it across all channels.

Related

Tween the texture on a TextureButton / TextureRect. Fade out Image1 while simultaneously fade in Image2

Character portrait selection. Clicking next loads the next image in an array, clicking back loads the previous image. Instead of a sharp change from one image to another, I want a variable-speed fading out of the current image and fading in of the new image. Dissolve/Render effects would be nice, but even an opacity tween 100->0 / 0-> 100 in x Seconds.
I really prefer not to use multiple objects on top of each other and alternating between them for "current texture".
Is this possible?
We can do Fade-in and Fade-out by animation modulate. Which is the simple solution.
For dissolve we can use shaders. And there is a lot we can do with shaders. There are plenty of dissolve shaders you can find online... I'll explain some useful variations. I'm favoring variations that are easy to tinker with.
Fade-in and Fade-out
We can do this with a Tween object and either the modulate or self-modulate properties.
I would go ahead and create a Tween in code:
var tween:Tween
func _ready():
tween = Tween.new()
add_child(tween)
Then we can use interpolate_property to manipulate modulate:
var duration_seconds = 2
tween.interpolate_property(self, "modulate",
Color.white, Color.transparent, duration_seconds)
Don't forget to call start:
tween.start()
We can take advantage of yield, to add code that will execute when the tween is completed:
yield(tween, "tween_completed")
Then we change the texture:
self.texture = target_texture
And then interpolate modulate in the opposite direction:
tween.interpolate_property(self, "modulate",
Color.transparent, Color.white, duration_seconds)
tween.start()
Note that I'm using self but you could be manipulating another node. Also target_texture is whatever texture you want to transition into, loaded beforehand.
Dissolve Texture
For any effect that require both textures partially visible, use a custom shader. Go ahead and add a ShaderMaterial to your TextureRect (or similar), and give it a new Shader file.
This will be our starting point:
shader_type canvas_item;
void fragment()
{
COLOR = texture(TEXTURE, UV);
}
That is a shader that simply shows the texture. Your TextureRect should look the same it does without this shader material. Let us add the second texture with an uniform:
shader_type canvas_item;
uniform sampler2D target_texture;
void fragment()
{
COLOR = texture(TEXTURE, UV);
}
You should see a new entry on Shader Param on the Inspector panel for the new texture.
We also need another parameter to interpolate. It will be 0 to display the original Texture, and 1 for the alternative texture. In Godot we can add a hint for the range:
shader_type canvas_item;
uniform sampler2D target_texture;
uniform float weight: hint_range(0, 1);
void fragment()
{
COLOR = texture(TEXTURE, UV);
}
In Shader Param on the Inspector Panel you should now see the new float, with a slider that goes from 0 to 1.
It does nothing, of course. We still need the code to mix the textures:
shader_type canvas_item;
uniform sampler2D target_texture;
uniform float weight: hint_range(0, 1);
void fragment()
{
vec4 color_a = texture(TEXTURE, UV);
vec4 color_b = texture(target_texture, UV);
COLOR = mix(color_a, color_b, weight);
}
That will do. However, I'll do a little refactor for ease of modification, later on this answer:
shader_type canvas_item;
uniform sampler2D target_texture;
uniform float weight: hint_range(0, 1);
float adjust_weight(float input, vec2 uv)
{
return input;
}
void fragment()
{
vec4 color_a = texture(TEXTURE, UV);
vec4 color_b = texture(target_texture, UV);
float adjusted_weight = adjust_weight(weight, UV);
COLOR = mix(color_a, color_b, adjusted_weight);
}
And now we manipulate it, again with Tween. I'll assume you have a Tween created the same way as before. Also that you already have your target_texture loaded.
We will start by setting the weight to 0, and target_texture:
self.material.set("shader_param/weight", 0)
self.material.set("shader_param/target_texture", target_texture)
We can tween weight:
var duration_seconds = 4
tween.interpolate_property(self.material, "shader_param/weight",
0, 1, duration_seconds)
tween.start()
yield(tween, "tween_completed")
And then change the texture:
self.texture = target_texture
Making Dissolve Fancy
We can get fancy we our dissolve effect. For example, we can add another texture to control how fast different parts transition form one texture to the other:
uniform sampler2D transition_texture;
Set it to a new NoiseTexture (and don't forget to set the Noise property of the NoiseTexture). I'll be using the red channel of the texture.
A simple solution looks like this:
float adjust_weight(float input, vec2 uv)
{
float transition = texture(transition_texture, uv).r;
return min(1.0, input * (transition + 1.0));
}
Where the interpolation is always linear, and the transition controls the slope.
We can also do something like this:
float adjust_weight(float input, vec2 uv)
{
float transition = texture(transition_texture, uv).r;
float input_2 = input * input;
return input_2 + (input - input_2) * transition;
}
Which ensure that an input of 0 returns 0, and an input of 1 returns 1. But transition controls the curve in between.
If you plot x * x + (x - x * x) * y in the range from 0 to 1 in both axis, you will see that when y (transition) is 1, you have a line, but when y is 0 you have a parabola.
Alternatively, we can change adjusted_weight to an step function:
float adjust_weight(float input, vec2 uv)
{
float transition = texture(transition_texture, uv).r;
return smoothstep(transition, transition, input);
}
Using smoothstep instead of step to avoid artifacts near 0.
Which will not interpolate between the textures, but each pixel will change from one to the other texture at a different instant. If your noise texture is continuous, then you will see the dissolve advance through the gradient.
Ah, but it does not have to be a noise texture! Any gradient will do. *You can create a texture defining how you want the dissolve to happen (example, under MIT license).
You probably can come up with other versions for that function.
Making Dissolve Edgy
We also could add an edge color. We need, of course, to add a color parameter:
uniform vec4 edge_color: hint_color;
And we will add that color at an offset of where we transition. We need to define that offset:
uniform float edge_weight_offset: hint_range(0, 1);
Now you can add this code:
float adjusted_weight = adjust_weight(max(0.0, weight - edge_weight_offset * (1.0 - step(1.0, weight))), UV);
float edge_weight = adjust_weight(weight, UV);
color_a = mix(color_a, edge_color, edge_weight);
Here the factor (1.0 - step(1.0, weight)) is making sure that when weight is 0, we pass 0. And when weight is 1, we pass a 1. Sadly we also need to make sure the difference does not result in a negative value. There must be another way to do it… How about this:
float weight_2 = weight * weight;
float adjusted_weight = adjust_weight(weight_2, UV);
float edge_weight = adjust_weight(weight_2 + (weight - weight_2) * edge_weight_offset, UV);
color_a = mix(color_a, edge_color, edge_weight);
Ok, feel free to inline adjust_weight. Whichever version you are using (this makes edges with the smoothstep version. With the other it blends a color with the transition).
Dissolve Alpha
It is not hard to modify the above shader to dissolve to alpha instead of dissolving to another texture. First of all, remove target_texture, also remove color_b, which we don't need and should not use. And instead of mix, we can do this:
COLOR = vec4(color_a.rgb, 1.0 - adjusted_weight);
And to use it, do the same as before to transition out:
self.material.set("shader_param/weight", 0)
var duration_seconds = 2
tween.interpolate_property(self.material, "shader_param/weight",
0, 1, duration_seconds)
tween.start()
yield(tween, "tween_completed")
Which will result in making it transparent. So you can change the texture:
self.texture = target_texture
And transition in (with the new texture):
tween.interpolate_property(self.material, "shader_param/weight",
1, 0, duration_seconds)
tween.start()

Calculating UV Coordinates in domain shader

I was trying to implement the terrain tutorial in Introduction to game programming by frank luna. I succeeded to implement it using the effect file.
When I try to separate the Vertex, hull, domain and pixel shaders, I got a very strange behavior in the terrain textures. After debugging I got that the problem is in calculating the UV texture coordinates in the domain shader.
Here is how I calculate the UV coordinates.
[domain("quad")]
DomainOut main(PatchTess patchTess,
float2 uv : SV_DomainLocation,
const OutputPatch<HullOut, 4> quad)
{
DomainOut dout;
// Bilinear interpolation.
dout.PosW = lerp(
lerp(quad[0].PosW, quad[1].PosW, uv.x),
lerp(quad[2].PosW, quad[3].PosW, uv.x),
uv.y);
dout.Tex = lerp(
lerp(quad[0].Tex, quad[1].Tex, uv.x),
lerp(quad[2].Tex, quad[3].Tex, uv.x),
uv.y);
// Tile layer textures over terrain.
dout.TiledTex = dout.Tex * 50.0f;
dout.TiledTex = dout.Tex*50.0f;
// Displacement mapping
dout.PosW.y = gHeightMap.SampleLevel(samHeightmap, dout.Tex, 0).r;
// NOTE: We tried computing the normal in the shader using finite difference,
// but the vertices move continuously with fractional_even which creates
// noticable light shimmering artifacts as the normal changes. Therefore,
// we moved the calculation to the pixel shader.
// Project to homogeneous clip space.
dout.PosH = mul(float4(dout.PosW, 1.0f), gViewProj);
return dout;
}
I am using quads for the domain shader.
After debugging using graphics analyzer, I got that in the domain shader the data is different from effect file from the domain shader I implemented altough the same code is used in both files.
What can be the problem?
I have an update to share with you, The data stream that enters to the domain shader is different from the effect file from the separated files. It is not the equation for the calculation.
What makes the data stream different, is there any way to change the order of patches enters the domain shader from the Hull shader.
This is the pixel shader code:
Texture2DArray gLayerMapArray : register(t3);
Texture2D gBlendMap : register(t1);
SamplerState samLinear
{
Filter = MIN_MAG_MIP_LINEAR;
AddressU = WRAP;
AddressV = WRAP;
AddressW = WRAP;
};
struct DomainOut
{
float4 PosH : SV_POSITION;
float3 PosW : POSITION;
float2 Tex : TEXCOORD0;
float2 TiledTex : TEXCOORD1;
};
float4 main(DomainOut pin) : SV_Target
{
//
// Texturing
//
float4 c0 = gLayerMapArray.Sample(samLinear, float3(pin.TiledTex, 0.0f));
float4 c1 = gLayerMapArray.Sample(samLinear, float3(pin.TiledTex, 1.0f));
float4 c2 = gLayerMapArray.Sample(samLinear, float3(pin.TiledTex, 2.0f));
float4 c3 = gLayerMapArray.Sample(samLinear, float3(pin.TiledTex, 3.0f));
// Sample the blend map.
float4 t = gBlendMap.Sample(samLinear, pin.Tex);
// Blend the layers on top of each other.
float4 texColor = c0;
texColor = lerp(texColor, c1, t.r);
texColor = lerp(texColor, c2, t.g);
texColor = lerp(texColor, c3, t.b);
return texColor;
}
Finally, the solution is that I should set the sampler from c++ code even if you have a sampler in the shader. I don't know why but this solved the problem.

How to color a texture in glsl

I need to modify during runtime the appearence of textures..
Some examples may be rendering them with a gray scale to indicate a deactivation, orange color for selection and so on
A little example that better shows what I would like to achieve
Right now my FS looks pretty simple
#version 330
in vec2 fragmentUV;
out vec4 outputColor;
uniform sampler2D textureNode;
void main()
{
outputColor = texture(textureNode, fragmentUV).rgba;
}
I thought I could control these few cases by setting an uniform variable to some hardcoded values...
That's how you can convert an image into grayscale: http://glsl.heroku.com/e#18369.1
float grayScale = dot(imageColor.rgb, vec3(0.299, 0.587, 0.114));
if (IsGrayScale){
gl_FragColor = vec4(grayScale, grayScale, grayScale, 1.0);
} else{
gl_FragColor = imageColor;
}

How can I display multiple separate textures (not multi-texturing) with OpenGL ES 2.0?

My iOS 4 app uses OpenGL ES 2.0 and renders elements with a single texture. I would like to draw elements using multiple different textures and am having problems getting things to work.
I added a variable to my vertex shader to indicate which texture to apply:
...
attribute float TextureIn;
varying float TextureOut;
void main(void)
{
...
TextureOut = TextureIn;
}
I use that value in the fragment shader to select the texture:
...
varying lowp float TextureOut;
uniform sampler2D Texture0;
uniform sampler2D Texture1;
void main(void)
{
if (TextureOut == 1.0)
{
gl_FragColor = texture2D(Texture1, TexCoordOut);
}
else // 0
{
gl_FragColor = texture2D(Texture0, TexCoordOut);
}
}
Compile shaders:
...
_texture = glGetAttribLocation(programHandle, "TextureIn");
glEnableVertexAttribArray(_texture);
_textureUniform0 = glGetUniformLocation(programHandle, "Texture0");
_textureUniform1 = glGetUniformLocation(programHandle, "Texture1");
Init/Setup:
...
GLuint _texture;
GLuint _textureUniform0;
GLuint _textureUniform1;
...
glActiveTexture(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D); // ?
glBindTexture(GL_TEXTURE_2D, _textureUniform0);
glUniform1i(_textureUniform0, 0);
glActiveTexture(GL_TEXTURE1);
glEnable(GL_TEXTURE_2D); // ?
glBindTexture(GL_TEXTURE_2D, _textureUniform1);
glUniform1i(_textureUniform1, 1);
glActiveTexture(GL_TEXTURE0);
Render:
...
glVertexAttribPointer(_texture, 1, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*) (sizeof(float) * 13));
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, _textureUniform0);
glUniform1i(_textureUniform0, 0);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, _textureUniform1);
glUniform1i(_textureUniform1, 1);
glActiveTexture(GL_TEXTURE0);
glDrawElements(GL_TRIANGLES, indicesCountA, GL_UNSIGNED_SHORT, (GLvoid*) (sizeof(GLushort) * 0));
glDrawElements(GL_TRIANGLES, indicesCountB, GL_UNSIGNED_SHORT, (GLvoid*) (sizeof(GLushort) * indicesCountA));
glDrawElements(GL_TRIANGLES, indicesCountC, GL_UNSIGNED_SHORT, (GLvoid*) (sizeof(GLushort) * (indicesCountA + indicesCountB)));
My hope was to dynamically apply the texture associated with a vertex but it seems to only recognize GL_TEXTURE0.
The only way I have been able to change textures is to associated each texture with GL_TEXTURE0 and then draw:
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, _textureUniformX);
glUniform1i(_textureUniformX, 0);
glDrawElements(GL_TRIANGLES, indicesCountA, GL_UNSIGNED_SHORT, (GLvoid*) (sizeof(GLushort) * 0));
...
In order to render all the textures, I would need a separate glDrawElements() call for each texture, and I have read that glDrawElements() calls are a big hit to performance and the number of calls should be minimized. Thats why I was trying to dynamically specifiy which texture to use for each vertex.
It's entirely possible that my understanding is wrong or I am missing something important. I'm still new to OpenGL and the more I learn the more I feel I have more to learn.
It must be possible to use textures other than just GL_TEXTURE0 but I have yet to figure out how.
Any guidance or direction would be greatly appreciated.
Can it be you're just experiencing floating point rounding issues? There shouldn't be any (except if a single privimitve shares vertices with different textures), but just to be sure replace this TextureOut == 1.0 with a TextureOut > 0.5 or something the like.
As a general advice, you are correct in that the number of draw calls should be reduced as much a possible, but your approach is quite odd. You are buying draw call reduction with fragment shader branching. Your approach also doesn't scale well with the overall number of textures, since you always need all textures in separate texture units.
The usual approach to reduce texture switches is to put all the textures into a single large texture, a so-called texture atlas, and use the texture coordinates to select the appropriate subregion in this texture. This also has some pitfalls (which are an entirely different question), but nothing comes for free.
EDIT: Oh wait, I see what you're actually doing wrong
glBindTexture(GL_TEXTURE_2D, _textureUniform0);
You're binding a texture to the current texture unit, but instead of the texture object you give this function a uniform location, which is complete rubbish (but might even work in some weird circumstances, since both uniform locations and texture objects are themselves just integers). Of course you have to bind the actual texture.

Depth buffer only show blue color

I'm trying to implement Light Prepass rendering in RenderMonkey. So far, in Normal+Depth pass, it seems like Normal buffer is getting correct result, but Depth buffer only show one color. How can I check if my Depth buffer is correct or not?
Workspace download link: http://www.mediafire.com/?jq3jmantyxw
The light blue is actually RGB values 0.0, 1.0, 1.0. Since depth is (usually) a single channel representing Z, when sampled from texture it's returned in the first channel, red. Missing channels green, blue and alpha will have 1.0 substituted by the hardware.
Your download link is non-functional, since it's been 2 years I suspect.
You should ensure your pixel shader is returning both COLOR0 and COLOR1 semantics (note that depth is a float4 despite the output being a single channel texture):
struct PS_OUT { float4 color : COLOR0; float4 depth : COLOR1; };
PS_OUT ps_main( PS_INPUT Input )
{
PS_OUT Output;
// your color shader here
Output.color = myFinalColor;
Output.depth = myFinalDepth; // e.g. Input.posz / Input.posw from your vertex shader
return Output;
}
Depending on your camera settings, you could get something like:

Resources