Textures

Started by
30 comments, last by Yura 11 years, 3 months ago

Hi,

I need to impose a specific texture on the triangle primitives.

So, I have a texture file: [attachment=13225:256colour3.png]

And I have a list of triangle primitives. I build a surface of these triangles. Each of triangle point contain data:

1) position

2) texture coordinate

Depands of texture coordinate on each point, I want to make color transition on the surface, like this:[attachment=13226:Capture1234.PNG]

But, using this shader


Texture ColorTexture;

sampler ColorTextureSampler = 
sampler_state 
{ 
texture = <ColorTexture> ; 
magfilter = NONE; 
minfilter = NONE; 
mipfilter = NONE; 
AddressU = wrap; 
AddressV = wrap; 
};

struct VertexShaderInput
{
    float4 Position : POSITION;
    float2 texCoord : TEXCOORD0;
};

struct VertexShaderOutput 
{
    float4 Position : POSITION;
    float2 texCoord : TEXCOORD0;
};

float4x4 worldViewProj;

VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
{
	VertexShaderOutput output = (VertexShaderOutput)0;
	
	output.Position = mul(input.Position, worldViewProj);
	output.texCoord = input.texCoord;
	
    return output;
}

float4 PixelShaderFunction(VertexShaderOutput input) : COLOR
{	
	return tex1D( ColorTextureSampler, input.texCoord.x);
}

technique Technique1
{
    pass Pass1
    {
	VertexShader = compile vs_2_0 VertexShaderFunction();
        PixelShader = compile ps_2_0 PixelShaderFunction();
    }
}

I receive this: [attachment=13227:Capture1236.PNG]

So, how should I modificate shader to receive such kind of color transition? Or, maybe, I should modificate texture file?

Advertisement

Pixel Shader and Texture are fine, your UV coordinates are wrong though.

how well is that plane subdivided?, the problem is that you can't get the output you want if your using 2 triangles per quad(and it looks like 9 quads), since the pixel shader linearly interpolates the uv values being passed in from the vertex's, this means you need to at least have the number of vertices equal to the number of data points, and then it has to be arranged to look like the quad, which could be very complex.

it might be better to actually take your pallete and build a 2D texture surface from your data points(and interpolate those data points yourself), then simply render that onto a quad.

edit: this might be possible in a compute or geometry shader though, but i don't believe you could achieve this easily with just vertex/pixel shader(although i'd love to see if someone does have a good solution).

Check out https://www.facebook.com/LiquidGames for some great games made by me on the Playstation Mobile market.

This is actually possible but you'd need a second texture, which would be a greyscale representation of the pattern you want. You do a standard tex2D lookup on that texture, then feed the result of that into your tex1D lookup to get the final colour.

Of course, by then you already have the pattern in a texture anyway so you may as well go all the way and put in the full RGB version, unless you have any specific reason not to (e.g. you want to swap out the RGB palette at runtime).

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.

Unless the sampling of the UV coord can be modified in the Pixel Shader (or VS) using a formulae of some kind, I dont think it can be done.

I'd also say that the 1d texture and .x in the pixel shader is 'strange' (though probably on purpose). Did you try it out as tex2d? You probably also need to look up the information of a specific uv depending on the pos on your plane (in the vertexshader and pass through the corresponding uv texcoord to the ps)

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me

It seems like one vertex shared by two faces has different uv coordinates, so you cannot get a smooth face.

how well is that plane subdivided?, the problem is that you can't get the output you want if your using 2 triangles per quad(and it looks like 9 quads), since the pixel shader linearly interpolates the uv values being passed in from the vertex's, this means you need to at least have the number of vertices equal to the number of data points, and then it has to be arranged to look like the quad, which could be very complex.

it might be better to actually take your pallete and build a 2D texture surface from your data points(and interpolate those data points yourself), then simply render that onto a quad.

edit: this might be possible in a compute or geometry shader though, but i don't believe you could achieve this easily with just vertex/pixel shader(although i'd love to see if someone does have a good solution).

You are right, here is 9 quads = 18 triangles = 16 points (data points). Each point has a texture coordinate. Number of vertices are equal to the number of data points since vertice IS a data point. Sorry, if I confused you. Each vertice contain coordinate and texture coordinate.

About 2D texture, not sure how it would help since my palette consists of vertical lines and V (y) coordinate is no needed (at the moment).

To my mind the problem is that textures are imposing on the separate element, not on all surface. But I may be wrong.

This is actually possible but you'd need a second texture, which would be a greyscale representation of the pattern you want. You do a standard tex2D lookup on that texture, then feed the result of that into your tex1D lookup to get the final colour.

Of course, by then you already have the pattern in a texture anyway so you may as well go all the way and put in the full RGB version, unless you have any specific reason not to (e.g. you want to swap out the RGB palette at runtime).

This is not the final surface, it can be changed. I need the universal solution, which can be implemented to any surface. As I understand, pattern will be sutable on for this surface. Changing of surface will require changing of pattern, or am I wrong?

i don't think you quite understand(or we don't quite understand what you want to accomplish?)

how well is that plane subdivided?, the problem is that you can't get the output you want if your using 2 triangles per quad(and it looks like 9 quads), since the pixel shader linearly interpolates the uv values being passed in from the vertex's, this means you need to at least have the number of vertices equal to the number of data points, and then it has to be arranged to look like the quad, which could be very complex.

it might be better to actually take your pallete and build a 2D texture surface from your data points(and interpolate those data points yourself), then simply render that onto a quad.

edit: this might be possible in a compute or geometry shader though, but i don't believe you could achieve this easily with just vertex/pixel shader(although i'd love to see if someone does have a good solution).

You are right, here is 9 quads = 18 triangles = 16 points (data points). Each point has a texture coordinate. Number of vertices are equal to the number of data points since vertice IS a data point. Sorry, if I confused you. Each vertice contain coordinate and texture coordinate.

About 2D texture, not sure how it would help since my palette consists of vertical lines and V (y) coordinate is no needed (at the moment).

To my mind the problem is that textures are imposing on the separate element, not on all surface. But I may be wrong.

I don't think you quite understand how the vertex->pixel shader works, yes you have 16 data/vertex points, and could even pass in the data that your trying to interpolate across those vertices, however the problem is how the vertex shader get's translated to the pixel shader. it is always going to be done in a perfectly linear system, your sample image does not move across the triangle perfectly linearly, if you could control the pixel shader translation's across the surface you could apply w/e formula you use to do this, but at the moment, with strictly vertex/pixel shader, and as far as i know(and i may be wrong, which would be pretty cool to learn), you can't control how the pixel shader translates that data.

this is why we suggest you construct a 2D pallete of those data points translated across your 2D surface, and then render this, which can be done on initialization, or even when their's a change in data points. with modern computer's you probably won't even notice a slow-down when doing this in real-time(but not every frame, just on every change, although you might still get smooth results with every frame, i would not recommend doing that at all.)

for example, let's forget about it as a triangle, and think of it as just a straight line, looking at your image, let's take the bottom 2 vertice's on the left side, now then for simplicity sake let's look at this as if it's only along a single axis(let's say x):

the first vertex has a position at: 0 x, the uv is set to 0 as well.

the second vertex has a position at: 1 x, and the uv is set to 1.

so, the pixel shader sees their are 50 pixels between those 2 points, so each pixel get's this for it's input:

position = v0.x+(v1.x-v0.x)/50

uv = v0.u + (v1.u-v0.u)/50

see how their's no room for creating a system which isn't perfectly linear(and as you can see in your sample image, the color's along that bottom left line are not equal parts from each other).

I hope this explanation helps you better understand your problem.

Check out https://www.facebook.com/LiquidGames for some great games made by me on the Playstation Mobile market.

I realy do not completely understand what should I do and it is my fault. I do not have enough knowledge and expirience for even understand all you are telling me. Sorry for that.

So, I modificated my shader for using 2 textures for lookup.


Texture ColorTexture;

sampler ColorTextureSampler = 
sampler_state 
{ 
texture = <ColorTexture> ; 
magfilter = NONE; 
minfilter = NONE; 
mipfilter = NONE; 
AddressU = wrap; 
AddressV = wrap; 
};

Texture AcrossTexture;

sampler AcrossTextureSampler = 
sampler_state 
{ 
texture = <AcrossTexture> ; 
magfilter = NONE; 
minfilter = NONE; 
mipfilter = NONE; 
AddressU = wrap; 
AddressV = wrap; 
};


struct VertexShaderInput
{
    float4 Position : POSITION;
    float2 texCoord : TEXCOORD0;
};

struct VertexShaderOutput 
{
    float4 Position : POSITION;
    float2 texCoord : TEXCOORD0;
};

float4x4 worldViewProj;

VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
{
	VertexShaderOutput output = (VertexShaderOutput)0;
	
	output.Position = mul(input.Position, worldViewProj);
	output.texCoord = input.texCoord;
	
    return output;
}

float4 PixelShaderFunction(VertexShaderOutput input) : COLOR
{	
	float4 TextureColor = tex2D(AcrossTextureSampler, input.texCoord);	
	float f = TextureColor.r;
	return tex1D(ColorTextureSampler, f );
}

technique Technique1
{
    pass Pass1
    {
        VertexShader = compile vs_2_0 VertexShaderFunction();
        PixelShader = compile ps_2_0 PixelShaderFunction();
    }
}

Texture tex1 = Texture.FromFile(d3dDevice, "vertical.png");
Texture tex2 = Texture.FromFile(d3dDevice, "across.png");//, 100, 132, 1, Usage.None, Format.L8, Pool.Default, Filter.None, Filter.None, 1);  // L8 - grayscale format, but using this advanced options gives strange resylts  
            effect.SetTexture("ColorTexture", tex1);
            effect.SetTexture("AcrossTexture", tex2);


//vertices
for (int j = 0; j < list.Count; j++)
                {
                    points.Add(new Vertex()
                    {
                        Coord = new Vector2(0, SomeTextureCoordinate),
                        Position = new Vector3(list[j].X, list[j].Y, list[j].Z),
                    });
                }

AcrossTexture: [attachment=13240:across.png]

ColorTexture: [attachment=13241:256colour2.png]

Result: [attachment=13239:C.PNG]

This topic is closed to new replies.

Advertisement