I won't edit the vertex shader at all, it currently passes through a position, which is all I need (I will get rid of the LightIntensity parameter).
So I will turn to the fragment shader itself.
First up are the variables:
vec3 color; vec2 position, useBrick;
I convert the colour into a float4 and the vec2s into a float2:
float4 color; float2 position, useBrick;
The next bit sets the position variable:
position = MCposition / BrickSize;
MCposition is the position value coming in from the vertex shader, which in our Cg shader is i.pos:
position = i.pos / BrickSize;
The next bit is a set of calculations.
position = i.pos / BrickSize; if (fract(position.y * 0.5) > 0.5) position.x += 0.5; position = fract(position); useBrick = step(position, BrickPct); color = mix(MortarColor, BrickColor, useBrick.x * useBrick.y); color *= LightIntensity;
I'm not sure if all the build in functions from GLSL exist in Cg, but I will assume they do as the functionality is normally similar. It will throw an error if I'm wrong. For now I can leave it the same except for deleting the bit about LightIntensity. The last bit outputs the colour value
gl_FragColor = vec4 (color, 1.0);
I will just copy the color variable into the corresponding line from my old shader:
So this is the end result"
Shader "BrickShader" { Properties { _BrickColor ("Brick Color", Color) = (1.0, 0.3, 0.2,1) _MortarColor ("Mortar Color", Color) = (0.85, 0.86, 0.84,1) _BrickSize ("Brick Size", Vector) = (0.30, 0.15, 0, 0) _BrickPct ("Brick Pct", Vector) = (0.90, 0.85, 0, 0) } SubShader { Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" float4 _BrickColor; float4 _MortarColor; float4 _BrickSize; float4 _BrickPct; struct v2f { float4 pos : SV_POSITION; }; v2f vert (appdata_base v) { v2f o; o.pos = mul (UNITY_MATRIX_MVP, v.vertex); return o; } half4 frag (v2f i) : COLOR { float4 color; float2 position, useBrick; position = i.pos / _BrickSize; if (fract(position.y * 0.5) > 0.5) position.x += 0.5; position = fract(position); useBrick = step(position, _BrickPct); color = mix(_MortarColor, _BrickColor, useBrick.x * useBrick.y); return half4(color); } ENDCG } } Fallback "VertexLit" }
When I first ran this it failed because I had forgotten to put in the underscores "_" before the variable names. The next time it has more fundamental problems. It said there was an implicit cast from float4 to float2 on this line:
position = i.pos / _BrickSize;
And it was completely right, of course, i.pos is a float4 while position is a float2. To get around this I select just the x and y components of i.pos, using a special shader notation:
position = i.pos.xy / _BrickSize.xy;
I also need to do the same further down:
useBrick = step(position, _BrickPct.xy);
Another error says "'fract' : no matching overloaded function found at line 14", which I guess means that the fract function doesn't exist in Cg. A quick look on Google shows that it is actually "frac".
There are similar issues for the other built in functions. This page is useful:
http://http.developer.nvidia.com/CgTutorial/cg_tutorial_appendix_e.html
mix also gives an error, the correct name is lerp (short for linear interpolation).
The last error is the following one which seems a bit more confusing:
Shader error in 'BrickShader': Program 'frag', variable/member "pos" has semantic "POSITION" which is not visible in this profile at line 40
It looks like it means that I can't access a position parameter in a fragment shader.
So I probably need to pass it as a non-position parameter. Looking back at the original vertex program I realised that MCposition was passed separately from the main position, and that is was, in fact the untransformed vertex position. I therefore added a new variable to the struct:
struct v2f { float4 pos : SV_POSITION; float4 untransformedPos; };
edited the vertex shader:
v2f vert (appdata_base v) { v2f o; o.pos = mul (UNITY_MATRIX_MVP, v.vertex); o.untransformedPos = v.vertex; return o; }
and changed the relevant line in the fragment shader:
position = i.untransformedPos.xy / _BrickSize.xy;
The result works and is shown above. It isn't exactly what I want it to look like but it's a start. The full code is here:
Shader "BrickShader" { Properties { _BrickColor ("Brick Color", Color) = (1.0, 0.3, 0.2,1) _MortarColor ("Mortar Color", Color) = (0.85, 0.86, 0.84,1) _BrickSize ("Brick Size", Vector) = (0.30, 0.15, 0, 0) _BrickPct ("Brick Pct", Vector) = (0.90, 0.85, 0, 0) } SubShader { Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" float4 _BrickColor; float4 _MortarColor; float4 _BrickSize; float4 _BrickPct; struct v2f { float4 pos : SV_POSITION; float4 untransformedPos; }; v2f vert (appdata_base v) { v2f o; o.pos = mul (UNITY_MATRIX_MVP, v.vertex); o.untransformedPos = v.vertex; return o; } half4 frag (v2f i) : COLOR { float4 color; float2 position, useBrick; position = i.untransformedPos.xy / _BrickSize.xy; if (frac(position.y * 0.5) > 0.5) position.x += 0.5; position = frac(position); useBrick = step(position, _BrickPct.xy); //useBrick = float2(0, 0); color = lerp(_MortarColor, _BrickColor, useBrick.x * useBrick.y); return half4(color); } ENDCG } } Fallback "VertexLit" }