Jump to content

[SOLVED] Updating Texture in Vertex Shader Dynamically


photo

Recommended Posts

I am trying to create a custom vertex, geometry and fragment shader. I would like to pass in a float texture and an rgb color texture every frame but am running into some problems. 

 

I have tried updating a meshImage with new test texture data every frame before passing it off to the vertex shader. In my vertex shader, the output of the value returned in the texture will pass through the geometry shader and the fragment shader before rendering a color (following the meshLines sample). Seems like my texture ("depthTexture") in the vertex shader is never set when I use 

material->setImageTextureImage(id, meshImage, 1); 

The values I am getting back in the shader are all zero, when I call: 

float4 texValue = depthTexture.SampleLevel(s_sampler_0,IN.texcoord_0.xy,0.0f);

I've attached the project I'm working out of and the accompanying material/shader files (D3D11AppQt.zip + data.zip). Here is the relevant code:
 

	Unigine::MaterialPtr material = dynamicMesh->getMaterial(0);
        Unigine::ImagePtr meshImage = Unigine::Image::create();
	int width = 512; int height = 424;
	meshImage->create2D(width, height, Unigine::Image::FORMAT_RGBA8);
	id = material->findTexture("depthTexture");
	if (id != -1)
	{
		int result = material->getImageTextureImage(id, meshImage);
		//int result = material->getProceduralTextureImage(id, meshImage);
		for (int y = 0; y < height; y++)
		{
			for (int x = 0; x < width; x++)
			{
                               // random test values
				Unigine::Image::Pixel p;
				p.i.r = 255; p.i.g = 255; p.i.b = 255; p.i.a = 255;
				p.f.r = .75; p.f.g = .75; p.f.b = .75; p.f.a = .75;
				//p.f.r = .5; p.f.g = 5.0; p.f.b = .5; p.f.a = 1.0;
				meshImage->set2D(x, y, p);
			}
		}

		material->setImageTextureImage(id, meshImage, 1);
		//material->setProceduralTextureImage(id, meshImage);
	}

My material (.mat file):

<materials version="1.00" editable="0">

  <!--
	/* Mesh lines material
	 */
	-->
  <material name="lumenous_tron" editable="0">

    <!-- options -->
    <options two_sided="1" cast_shadow="0" receive_shadow="0" cast_world_shadow="0" receive_world_shadow="0"/>

    <!-- ambient shaders -->
    <shader pass="ambient" object="mesh_dynamic"
	vertex="core/shaders/lumenous/lumenous_tron_vertex.shader"
        geometry="core/shaders/lumenous/lumenous_tron_geometry.shader"
	fragment="core/shaders/lumenous/lumenous_tron_fragment.shader"/>

    <texture name="depthTexture" anisotropy="1" pass="ambient"/>

    <parameter name="customVector" type="constant" shared="1">0.0 0.0 0.0 0.0</parameter>
    <parameter name="customMatrix" type="array" shared="1"/>
    
  </material>

</materials>

and vertex shader:

Texture2D depthTexture : register(t0);

/*
 */
VERTEX_OUT main(VERTEX_IN IN) {
	
	VERTEX_OUT OUT;
	
	float4 row_0 = s_transform[0];
	float4 row_1 = s_transform[1];
	float4 row_2 = s_transform[2];
	
	float4 position = IN.position;
	OUT.position = mul4(row_0,row_1,row_2,position);
	
	float4 previous = float4(IN.texcoord_1.xyz,1.0f);
	OUT.texcoord_0 = float4(mul4(row_0,row_1,row_2,previous).xyz,IN.texcoord_1.w);
	OUT.texcoord_1 = IN.texcoord_2;
	
	float4 texValue = depthTexture.SampleLevel(s_sampler_0,IN.texcoord_0.xy,0.0f);
	//float4 texValue = depthTexture.Sample(s_sampler_0,IN.texcoord_0.xy);
	//float4 texValue = float4(.4, 0.0, 0.0, 1.0);
	if(texValue.x < .5)
	{
		OUT.texcoord_0 = float4(1.0, 0.0, 0.0, 1.0);
		OUT.texcoord_1 = float4(1.0, 0.0, 0.0, 1.0);
	}
	else
	{
		OUT.texcoord_0 = float4(0.0, 0.0, 1.0, 1.0);
		OUT.texcoord_1 = float4(0.0, 0.0, 1.0, 1.0);
	}
	
	return OUT;
}

Can you point me in the right direction? How do I pass in a texture to a vertex shader every frame and read it's values?

​Thanks!

D3D11AppQt.zip

data.zip

Link to comment

Hello raj,

 

I would try to add the following two XML attributes to the texture parameter in your material file:

<texture name="depthTexture" anisotropy="1" pass="ambient" unit="0" shader="vertex"/>

I think by default textures are only visible to the fragment shader (in d3d11 at least)

I don't know how pass matrices to a shader, so I don't know if that is working.

 

Good luck and cheers

 Helmut

Link to comment
  • 2 weeks later...

Hi there, Raj!

Looks like you set wrong texture type in your .mat file. Just remove type="procedural" and just create new Image, fill it with data and then use Material::setMaterialTextureImage function.

Take a look at data/samples/materials/procedural_00 sample.

Link to comment
×
×
  • Create New...