- Home /
How to reduce temporary register use in shader?
Okay, for you cg shader gurus out there
I am trying to write a simple unlit transparent shader that supports a clipping rectangle. This is my code...
Properties { _MainTex ("Base (RGB)", 2D) = "white" {} _cliprect ("Clip Rectangle", Vector) = (-1,-1,-1,-1) } SubShader { Tags { "RenderType"="Opaque" } LOD 200Shader "Custom/ClippingUnlitTransparent" {
CGPROGRAM #pragma surface surf Unlit #include "UnityCG.cginc"
half4 LightingUnlit (SurfaceOutput s, half3 lightDir, half atten) { half4 c; c.rgb = s.Albedo; c.a = s.Alpha; return c; } sampler2D _MainTex; float4 _cliprect;
struct Input { float2 uv_MainTex; float4 screenPos; }; void surf (Input IN, inout SurfaceOutput o) { float2 screenPosition = IN.screenPos.xy / IN.screenPos.w; screenPosition.xy = ((screenPosition.xy*0.5)+0.5) * _ScreenParams.xy; if ((_cliprect[0]<0) _cliprect[0]=0; if (_cliprect[1]<0) _cliprect[1]=0; if (_cliprect[2]<0) _cliprect[2] = _ScreenParams.x; if (_cliprect[3]<0) _cliprect[3]= _ScreenParams.y; if (screenPosition.x>=_cliprect[0])&& (screenPosition.x<=_cliprect[2])&& (screenPosition.y>=_cliprect[1])&& (screenPosition.y<=_cliprect[3])){ half4 c = tex2D (_MainTex, IN.uv_MainTex); o.Albedo = c.rgb; o.Alpha = c.a; } else{ o.Albedo = (0,0,0); o.Alpha = 0; } } ENDCG } FallBack "Diffuse" } It compiled fine until I put the final if check in
(screenPosition.x<=_cliprect[2])&& (screenPosition.y>=_cliprect[1])&& (screenPosition.y<=_cliprect[3])){ Now it gives me the error "Not enough registers, needs 9 (compiling for flash) at line 11" What can I do to fix this?if (screenPosition.x>=_cliprect[0])&&
I cut out the if that sets the rect and ist happier now. will just have to be less idiot proof I guess
Answer by Bunny83 · Jun 23, 2012 at 12:34 AM
The GPU works like is a DSP (Digital signal processor) in a pipeline mode. It's designed to perform the same actions on a huge stream of data. Branches are a bad idea in a shader. Try to avoid them. It's way better to transform your "condition" into a value that can be computed and used as multiplier.
Those:
if ((_cliprect[0]<0) _cliprect[0]=0;
if (_cliprect[1]<0) _cliprect[1]=0;
if (_cliprect[2]<0) _cliprect[2] = _ScreenParams.x;
if (_cliprect[3]<0) _cliprect[3]= _ScreenParams.y;
really should be done by your program and not by the shader for every pixel!! You should take care of valid shader parameters from outside.
I did remove that and it solved the register issue. Just goes contrary to 25 years of defensive program$$anonymous$$g instinct ;)
But shaders work way different to normal x86 code ;) I'm not a shader expert at all, but the basic concept of a CPU and GPU are very different since they have different targets.
A pipeline processor has a fix pipeline of operations and the data is pushed through the pipeline and get processed. A GPU is optimised for 32-bit floating point arithmetic. It's not a logic processor.
Your answer
Follow this Question
Related Questions
Solid color flash entire screen 2 Answers
flash problem 2 Answers
Flash Prevent Digonal Movement 1 Answer
Separate UI in Flash - examples? 2 Answers
Error #2070: Security sandbox violation in AIR with local file 1 Answer