Search Unity

Looking into the Skull

Discussion in 'Shaders' started by tfrantz, Mar 18, 2018.

  1. tfrantz

    tfrantz

    Joined:
    Dec 7, 2017
    Posts:
    7
    I've been having a bit tricky time trying to get a virtual craniotomy to work out.

    I've been trying to modify one of the hololens sdk vert/frag shaders to achieve this effect, but unfortunately for me my talents lay elsewhere :/

    I found and modified a surface shader to achieve a similar effect I want... however I would like to keep my current vert/frag shader. Picture of what I would like to happen.
    photo2.JPG

    The approach I've been trying is to raycast and apply a clip to every pixel if falls within a certain radius of the raycast impact, via the following code added I've been testing out in its own shader.

    Code (CSharp):
    1. Shader "Custom/Cranio" {
    2.     Properties{
    3.         _Color("Color", Color) = (1,1,1,1)
    4.         _ObjPos("ObjPos", Vector) = (0,0,0)
    5.         _ObjRad("Craniotomy Size", Float) = 0.001
    6.     }
    7.  
    8.         SubShader{
    9.             pass{
    10.  
    11.                 Tags { "Queue" = "Geometry" }
    12.                 LOD 150
    13.                 CGPROGRAM
    14.                 #pragma vertex vert
    15.                 #pragma fragment frag
    16.  
    17.                 float4 _ObjPos; //World Position of Raycast
    18.                 float _ObjRad; //Radius to Check
    19.                 float4 _Color;
    20.                 int check;
    21.  
    22.                 struct a2v {
    23.                     float4 pos : POSITION;
    24.                 };
    25.  
    26.                 struct v2f {
    27.                     float4 pos : SV_POSITION;
    28.                 };
    29.  
    30.                 v2f vert(a2v input) {
    31.                     v2f output;
    32.  
    33.                     //Change Local Vertex Position to World Apace and Find Dist Value
    34.                     float4 WorldPosition = mul(unity_ObjectToWorld, input.pos);
    35.                     float4 Delta = WorldPosition - _ObjPos;
    36.                     float Dist = length(Delta);
    37.  
    38.                     if (Dist < _ObjRad) {
    39.                         check = -1;
    40.                     }
    41.                     else {
    42.                         check = +1;
    43.                     }
    44.  
    45.                     //Convert Vertex local Positon to Screen Posiiton for Output
    46.                     output.pos = UnityObjectToClipPos(input.pos);
    47.                     return output;
    48.                 }
    49.  
    50.                 float4 frag(v2f i) : SV_Target{
    51.                     clip(check); //Discard if set < 1
    52.                     return  _Color;
    53.                 }
    54.                 ENDCG
    55.             }
    56.         }
    57.         FallBack "Diffuse"
    58. }
    59.  
    Is there something wrong with how this is implemented? I'm not getting any clipping of my texture.

    Below is what I'm trying to get to work on the above Shader.

    photo2.JPG photo3.JPG photo4.JPG
     
  2. tfrantz

    tfrantz

    Joined:
    Dec 7, 2017
    Posts:
    7
    An update: I've decided to use a surface shader, and all is fine when not modifying the alpha, but when I do there are two problems:
    1. Don't get the right layering of models (inside to out),
    2. Some models look as though they're inside-out
    3. I can see both sides of the model with 100% alpha

    Transparency always worked well when using the default unity 2 sided shader, but with my own I'm afraid not so much.
    One solution is to change shaders when I want different effects, but I'm thinking it's possible to have a two sided shader which:
    1. 2 sided
    2. Alpha works well
    3. I can clip pixels near to a point

    After spending some hours reading online, this is what I came up with: Any advice would be appreciated to get this working as it should!

    Code (CSharp):
    1.  
    2. Shader "Frantz/ModelShader" {
    3.     Properties{
    4.         _Color("Material Color (RGB)", Color) = (0,0,0,1)
    5.  
    6.         _Origin("Origin (World Space)", Vector) = (0,0,0,0)
    7.         _Radius("Radius", Range(0,1)) = 0
    8.  
    9.         _Glossiness("Smoothness", Range(0,1)) = 0
    10.         _Metallic("Metallic", Range(0,1)) = 0.0
    11.  
    12.         _Conversion("Halo Effect (RGB)", Color) = (255,90,0,255)
    13.         _ConvertEmission("Halo Intensity", Range(0,1)) = 0.5
    14.         _ConvertDistance("Halo Distance", Range(0,.02)) = 0.005
    15.  
    16.         _EmitCol("Emisison Color (RGB)", Color) = (1,1,1,1)
    17.         _Emission("Surface Intensity", Range(0,1)) = 1
    18.  
    19.     }
    20.         SubShader{
    21.         Tags{ "Queue" = "Transparent" "RenderType" = "Transparent" }
    22.         LOD 100
    23.  
    24.         //ZWrite On
    25.         //ZTest LEqual
    26.  
    27.         Blend SrcAlpha OneMinusSrcAlpha
    28.    
    29.         Cull Front
    30.         CGPROGRAM
    31.         //Target Only for Hololens
    32.         #pragma target 5.0
    33.         #pragma only_renderers d3d11
    34.  
    35.         //Shaders
    36.         #pragma surface surf Standard fullforwardshadows alpha
    37.         #pragma vertex vert
    38.  
    39.         //Input for Surface Shader
    40.         struct Input {
    41.         float3 worldPos;
    42.         };
    43.  
    44.         void vert(inout appdata_full v) {
    45.             v.normal *= -1;
    46.         }
    47.    
    48.         half _Glossiness;
    49.         half _Metallic;
    50.         half _ConvertDistance;
    51.         half _ConvertEmission;
    52.         half4 _Color;
    53.         half4 _Conversion;
    54.    
    55.         half _Radius;
    56.         float3 _Origin;
    57.    
    58.         void surf(Input IN, inout SurfaceOutputStandard  o) {
    59.             half dist = distance(IN.worldPos, _Origin);
    60.             clip(dist - _Radius);
    61.    
    62.             float convert_mask = (dist - _Radius) / _ConvertDistance;
    63.             convert_mask = clamp(convert_mask, 0, 1);
    64.    
    65.             fixed4 albedo = _Color;
    66.             albedo *= convert_mask;
    67.             fixed4 convert = _Conversion;
    68.             convert *= 1.0 - convert_mask;
    69.             o.Albedo = albedo.rgb + convert.rgb;
    70.             o.Emission = convert.rgb * _ConvertEmission;
    71.             o.Metallic = _Metallic;
    72.             o.Smoothness = _Glossiness;
    73.             o.Alpha = albedo.a;
    74.         }
    75.         ENDCG
    76.  
    77.         Cull Back
    78.         CGPROGRAM
    79.         //Target Only for Hololens
    80.         #pragma target 5.0
    81.         #pragma only_renderers d3d11
    82.  
    83.         //Shaders
    84.         #pragma surface surf Standard fullforwardshadows alpha
    85.  
    86.         //Input for Surface Shader
    87.         struct Input {
    88.             float3 worldPos;
    89.         };
    90.  
    91.         //Veriables
    92.         half _Glossiness;
    93.         half _Metallic;
    94.         half _ConvertDistance;
    95.         half _ConvertEmission;
    96.         half4 _Color;
    97.         half4 _Conversion;
    98.         half _Emission;
    99.         half4 _EmitCol;
    100.  
    101.         half _Radius;
    102.         float3 _Origin;
    103.  
    104.         void surf(Input IN, inout SurfaceOutputStandard  o) {
    105.             half dist = distance(IN.worldPos, _Origin);
    106.             clip(dist - _Radius);
    107.  
    108.             float convert_mask = (dist - _Radius) / _ConvertDistance;
    109.             convert_mask = clamp(convert_mask, 0, 1);
    110.  
    111.             fixed4 albedo = _Color;
    112.             albedo *= convert_mask;
    113.             fixed4 convert = _Conversion;
    114.             convert *= 1.0 - convert_mask;
    115.             o.Albedo = albedo.rgb + convert.rgb + _EmitCol.rgb*_Emission;
    116.             o.Emission = convert.rgb * _ConvertEmission;
    117.             o.Metallic = _Metallic;
    118.             o.Smoothness = _Glossiness;
    119.             o.Alpha = albedo.a;
    120.         }
    121.         ENDCG
    122.     }
    123.  
    124.     Fallback "Diffuse"
    125. }
    This is how things are looking when I don't include the word "alpha" in the pragma surface bit:
    Cranio.JPG Head.JPG HeadClip.JPG

    Then trying to use an alpha:
    HeadAlpha.JPG Capture.JPG *Disaster!
     
  3. Zee_pso

    Zee_pso

    Joined:
    Nov 12, 2016
    Posts:
    31
    Are you using separate models for the head, skull, and brain? I would try using the stencil buffer. You could add a sphere around the mouse pointer (or whatever pointer your using) with a stencil mask, which will stop rendering the head, showing the brain inside.