Problems with Vertex Texture Fetch

I’m working on a clipmapping algorithm( http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter02.html), and I can’t seem to get tex2D or tex2Dlod to work in the vertex shader. It either gives a profile error (if only_renderers d3d9 isn’t declared) or the return value is all zeros and no displacement happens.

Is there any sample code for displacement mapping in Unity?

Shader "GeoMipDisplacement" {
	Properties {
		_Color ("Main Color", Color) = (1,1,1,1)
		_MainTex ("Base (RGB)", 2D) = "white" {}
		_HeightMap("Bumpmap", 2D) = "bump" {}
		_NormalMap("NormalMap", 2D) = "bump" {}
		_TexOffset( "ToroidOffset", Vector ) = (0.0, 0.0, 0.0, 0.0)
	}
	SubShader 
	{
		Pass {
			CGPROGRAM
			
			#pragma only_renderers d3d9 // Gives profile error without it
			#pragma target 3.0
			#pragma vertex vert
			#pragma fragment frag
			#pragma fragmentoption ARB_fog_exp2
			#include "UnityCG.cginc"

			struct v2f 
			{
				V2F_POS_FOG;
				float3  color : COLOR0;
				float2  tex : TEXCOORD0;
			};
			
			struct vertex
			{
				float2 texcoord : TEXCOORD0;
				float4 pos : POSITION;
			};
			
			uniform half4 _Color;
			uniform sampler2D _HeightMap;
			uniform sampler2D _NormalMap;

			v2f vert (appdata_base v)
			{
				v2f o;
				PositionFog( v.vertex, o.pos, o.fog );
				o.tex	= v.texcoord;
				o.pos.y += tex2Dlod( _HeightMap, float4(v.texcoord.xy, 0, 1) ).x * 100.0;
				return o;
			}

			half4 frag (v2f i) : COLOR
			{
				half3 h3Height	= tex2D( _HeightMap, i.tex );
				half4 h4Norm	= tex2D( _NormalMap, i.tex );
				
				return half4(h3Height.x, h3Height.y, h3Height.z, 1.0 );
			}
			ENDCG
		}
	}
	FallBack "Diffuse", 1
}

The shader code is kind of frankensteined together right now, but my main focus is why vertex texture fetch doesn’t work. The texture should be correct because it draws if I just directly read and output it in the frag shader.

I’m not sure about this, but it could be that tex2D simply isn’t supported at all in Unity’s Cg implementation.

Potentially its just as well the common problem: OpenGL
As nice as it might be, as strange and non standardized it is in various higher end features and I’m unsure which of those are supported in CG crossplatform wise if they are available at all.
Another problem is ATI in respect to VTF as they didn’t do it as it was meant so its possible that you can’t use it at all on opengl without vendor specific code to set it up.

From what I’ve browsed around and seen, websites seem to say that floating point texture formats are required for DirectX and OpenGL VTFs.

Could that be it since Unity3D doesn’t seem to support floating point textures at the moment?

Depends on the texture required.
Fact is that opengl does not support the normally used / required format at all (A32R32G32B32 textures to be precise).
Guess thats why it works if you tell it that it is going to be a dx only shader as DX has had support for them for years.

Unity will support floating point textures in Unity 2.6 very soon.

But sampling textures in the vertex shader is not supported right now (and won’t be in 2.6 either).

Thank everyone for the replies.

So when you say they won’t be supported even in 2.6 - what else besides floating point textures would limit using tex2D in the vertex shader

Well, the “engine” has to support reading textures in the vertex shader. Unity does not support that right now (mostly because it’s hard to do that accross D3D and OpenGL; and there were not many requests for the feature either…).

Count me as a requester of Vertex texture fetching as well. I need it. I actually got pretty far in the developing of some stuff, before realising I couldn’t do it (my own fault, I could just have researched before starting my little adventure…). Will it be supported in Unity 3.0?

You can vote for adding vertex shader texture fetch to unity here:
http://feedback.unity3d.com/forums/15792-unity/suggestions/483814-graphics-vertex-shader-texture-fetch

I need to do some hardcore vector displacement mapping as well, and lack of this feature sorely stomped on my ability to get this done effectively. I’ve cast my vote over at UserVoice… but for now I was wondering if there’s any kind of workaround? Is this something I can provide two sets of Cg, one for GL and one for DX, that manage to grab pixel data?

Doing the texture lookups in-engine is far too costly. I was really hoping a vertex shader could help…

Just to give my support to the feature. Was just about to try and implement it, when I discovered that its not supported in Unity. Have added my votes to the wishlist.

Very disappointing, along with lack of support for dds format (beyond a single image), 3D textures and I suspect passing generic attributes isn’t supported either?

Is there anyway for a developer to add support for any of these features, as a plugin or something that interfaces with the Unity 3d engine?

So frustrating to finally develop with a great looking editor and engine with shaders only to find much of the stuff I want to try is not possible due to lack of support, sometimes for the most basic feature (3D texture). I’m not crying out for Dx11 or anything like that, but this stuff has been around for years.

If you license unity sources.
Otherwise commonly no.

The world does not consist out of DX only, there is unhappily OSX and their OpenGL implementation which is basically OpenGL 2.x …

It’s not that OpenGL is unable to do Vertex Texture Fetch, it’s just that it was not properly standardized. For versions prior to OpenGL 3.0, the feature was optional, and thusly excluded in allot of the lower end cards, essentially making it unreliable at best on cards that do not support OpenGL 3.0- (Nvidia completely skipped OpenGL 3.0 until 2008 and both ATI and Nvidia’s lower end cards are unsupportive)

As Unity uses compiles to ARB, we don’t have vertex texturing. Because of the major structure changes for 3.0 (Aswell as the removal of core legacy features from 3.1 on), it’s probably in our best interests for Unity not to suddenly decide mandate support for this. (While there are ways to do it, it would have to be done at a different level then is exposed)

On the other hand, with DirectX (which is what most of the Vertex Texturing examples you see are done in) has mandated support for vertex texture reads from DirectX 9.0c, or all cards since 2005-

Now, while Shaderlab supports inserting either Cg or GLSL, you can’t insert HLSL snippets- You can, however, insert the assembly level vs_3_0 programs (As you can see done on some of the more extreme fallbacks present in the builtin examples), so if you manually compile your HLSL down to vs_3_0 you should be able to do vertex texture fetches in Unity, but only with DirectX. (See the MSDN Documentation at Instructions - vs_3_0 - Win32 apps | Microsoft Learn for more information on working on this level, and try opening the compile shaders in Unity for a better look at how to use pre-compiled code in your shader programs)

thanks for the info guys, very useful. I’ve not kept up to date on OpenGL for a while. Surprised it fell so far behind in respect to texture fetch. I always liked its plugin/extension nature as I thought it would keep it ahead of the curve, apparently not. Never have understood why openGL appears to be constantly crippled in some feature or other on Macs.

I can see that from you’ve said its not going to be as simple as supporting an extension or OpenGL 3.0, which is a great shame.

I might well investigate the DX compile to vs3 route mentioned when I get some free time. It sounds promising and interesting to explore.

Guess I’ve just been surprised that 3D textures aren’t support and dds isn’t really, both of which could have been very useful recently to me.

In addition it would appear there is also no means to provide attribute arrays other than those Unity offers? I’m still looking into this, so if i’m mistaken please tell me. I guess a workaround would be to use something like vertex colour array to send data?
thanks

Thats the theory.
Practically ATI skipped it even with the first generation of SM3 cards. It took till the HD 2300+ to finally get VTF support(ATI never was really following the requirements in relation to a Shader Model)

Intel took until 2008 or so to support it, when they were forced due to the WDDM driver support on Windows Vista with the X3100 or even X4500