1

I'm porting a custom shader to make it work on mobile phones since shaders inside mobiles can not have if statements.

I tried replacing the if statements of my code with the ? operator but I can not compile in Unity without errors. I'm pretty new to c# so it is obvious to myself I am missing something here to complete this. Any advice from more experienced programmers here? Many thanks to you all.

// The original code is commented.

I also tried to store the result inside a variable and return it but also didn't work.

/*  
if (charCol.r > .8f) 
{
    if(_monochromatic == 1)
        return float4(0, gray, 0, 1);
    else
        return col;
}
else 
{
    return col * _brightness;
}   
*/

charCol.r > .8f ? (_monochromatic == 1) ? return float4(0, gray, 0, 1) : return col : return col * _brightness;

Error message:

Shader error in 'Custom/Shader': syntax error: unexpected token 'return'

Yong Shun
  • 35,286
  • 4
  • 24
  • 46
H_7
  • 287
  • 1
  • 5
  • 18

2 Answers2

2

You should return as below:

return charCol.r > .8f 
    ? ((_monochromatic == 1) ? float4(0, gray, 0, 1) : col) 
    : col * _brightness;

Small opinion:

Even you can return value with the ternary operator, you may get a headache if the logic is complex and difficult to maintain.

Yong Shun
  • 35,286
  • 4
  • 24
  • 46
  • 1
    wow, light in my head, thanks! Gonna try right now. The return before everything makes sense but I'm for sure unable to figure out by myself. The double parenteses I should realised myself. I hope it works, I will coment here soon. Thanks again! – H_7 Feb 08 '22 at 06:19
  • 1
    so cool ! It works @Yong Shun . Can't thanks you enough! There is no more logic to convert, so I guess no headaches for now. But I understood your point,, it is so dificult to read this code, the if statement is much cleaner and easier to mantain. I will build to Android and will confirm it works there too now. Cheers!!! – H_7 Feb 08 '22 at 06:30
  • Headaches for now... it didn't work. Black screen of death. I will debug and return here. – H_7 Feb 08 '22 at 06:56
  • Just to clarify, it works on unity editor, after compiled it gives black screen on Android Mobile device. – H_7 Feb 12 '22 at 00:22
1

A ternary operator runs a test and resolves to one value if the test is true or another value if the test is false

 var age = person.Age > 21 : "adult" : "child";

The age is tested, one of the values is picked, the expression as a whole resolves to some string and age is this a string. Because the whole thing is effectively a value it can be returned

You might be tempted to nest these; it's possible but I'd say "only do it if it's simple" like:

var age = person.Age > 21 : "adult" : (person.Age > 12 ? "teenager" : "child");

This rapidly descends into a mess if you try to take it much further. Instead prefer a switch expression:

var age = person.Age switch {
  >21 => "adult",
  >12 => "teenager",
  _ => "child"
};

You can read this by imagining the compiler prefixes every line with the thing before the switch, the => is like "then" and the _ is like "else":

var age = switch {
  person.Age>21 then "adult",
  person.Age>12 then "teenager",
  else then "child"
};

And of course with anything that resolves to a value you don't have to store it in a variable before you return it.. you ca swap var age = for return on anything you see here

Caius Jard
  • 72,509
  • 5
  • 49
  • 80