How do I access material properties in CG?

Hi,

my problem is actually very basic. For a postprocessing shader I need a map of all fragment’s diffuse colors and specularities. I’m trying to write them to a RenderTarget in a dedicated render pass, with a very simple shader, just writing the material’s diffuse color to RGB and the specularity to A. However, I’m having a hard time to figure out how to access them in my shader. I cannot find anything related in UnityCG.cginc, the only hint I found was in the online docu, stating something about _ModelLightColor, which doesn’t seem to exist anymore (using Unity 4.2)

	v2f vert( appdata_base v ) {
		v2f o;
		o.pos = mul( UNITY_MATRIX_MVP, v.vertex );

		o.col = ???

		return o;
	} 
	
	half4 frag(v2f i) : COLOR {
		return half4( i.col, 1.0 );
	}

Could anyone provide a very simple solution to what I’m trying to do?

Thanks a lot!

This would be a good application for replacement shaders. Write a shader that outputs what you want, render the scene to a rendertexture using that shader, and then use the rendertexture as input to your image effect.

Well, that’s exactly what I’m doing. My question relates to that “write a shader that outputs what you want” part. The challenge is just to figure out how to GET that output I want, in order to write it.

Any suggestions, anybody? I’m sure this is really simple.

I think the part you’re missing is on that page:

You can still access the material properties as usual on each object. It’s only the shader that is replaced.

I know, I did this before, with values such as normals, depth, etc. Perhaps my issue is that basic that it’s not quite clear what I’m asking for: How do I access the material properties? Where do i get the material’s diffuse rgb, specular power, etc.? I cannot figure out what the names of the respective variables are.

It depends on the material–or more specifically, the properties used by the default shader of the material. So if you’re using the built-in specular shader, you would want to declare the uniforms:

sampler2D _MainTex;
float4 _MainTex_ST;
fixed4 _Color;
half _Shininess;

And then use them in your fragment shader in the same way the specular shader uses them:

	fixed4 tex = tex2D(_MainTex, IN.uv_MainTex);
	fixed3 diffuse = tex.rgb * _Color.rgb;
	fixed specular = _Shininess;
	return fixed4(diffuse, specular);

Note that IN.uv_MainTex is computed in the vertex shader with TRANSFORM_TEX(tex,name).

Check out the built-in shaders for their source, as well as the TRANSFORM_TEX macro in UnityCG.cginc.

Thanks a ton, Daniel, you saved my day!!

For the future: where am I supposed to find infos like this? Although this stuff is really basic, I cannot find it documented, I just stumble upon it here and there, by accident, which makes workig with Unity quite tedious. I mean, having to declare a vector “_Color” is not something I’d just guess. Sometimes I have the feeling like the documentation does not start from the (essential) beginning. Therefore: am I missing something?

You can download the default shaders source at http://unity3d.com/unity/download/archive and see what they name their properties.

This nuance is one of those things that you have to infer from the shader replacement documentation. It isn’t stated as explicitly as I would like.

If you have many different kind of materials in your Project, you cant write a replacement shader to get diffuse and speculars for all of the variations but only one type of it.
Its better to render the scene itself to a rendertexture and get the current scene data out of it.

I agree that Unity’s documentation is missing a lot of important information, especially when it comes to shaders and high-level design. In this case, though, there is actually a page on accessing shader properties in Cg.

Thanks, I’m not sure if I saw this page, maybe I did some time ago. Still, it is very unclear and it actually raises more questions. I cannot recognize a pattern in linkage of the names in properties and declarations, or a consistent prefix one has to use, or whatever. Maybe it is just considering the declaration order? I don’t hope it is, because I’d consider this very bad design. What if I have additional uniforms, declared above, below, or in between, would it then break the functionality of the shader due to wrong property-to-uniform-linkage?

Anyway, this is the problem I usually have with the (shaderlab) docu – it often raises more questions than it answers and I end up spending time I don’t have with experimenting and guessing. Just saying.