Search Unity

_World2Object and _Object2World problem

Discussion in 'Shaders' started by KuangZheng, Aug 23, 2013.

  1. KuangZheng

    KuangZheng

    Joined:
    Feb 25, 2013
    Posts:
    75
    I have a plane model,and it's divided to some parts. I write shader for them and they share the same material.But i find that some model cannot get correct _World2Object and _Object2World.

    I code this in fragment funtion :
    Code (csharp):
    1. return float4(_World2Object[0][0],_World2Object[1][1],_World2Object[2][2],1);
    and get this
    $Screen Shot 2013-08-23 at 下午12.10.19.png

    the red part and white part are used the same material. I move or rotate the plane,the red part can change color,but the white part always white,so I guess the _World2Object and _Object2World not change value.

    this is the whole shader code:
    Code (csharp):
    1.  
    2. Shader "Custom/EF3 Fighter (2)" {
    3.     Properties {
    4.         _MainTex ("Base (RGB)", 2D) = "white" {}
    5.         _NormalTex ("normal Texture", 2D) = "white" {}
    6.         _ReflectTexPlane ("reflect texture", 2D) = "white" {}
    7.  
    8.         _SpecularShiness ("Specular Shiness", Float) = 50
    9.         _ReflectRatio("Reflect Ratio", Float) = 0.1
    10.        
    11.         _RimColor ("Rim Color", Color) = (0.29,0.4,0.4,0.0)
    12.         _RimPower ("Rim Power", Range(0.5,16.0)) = 11.0
    13.  
    14.     }
    15.     SubShader {
    16. //      Tags { "RenderType"="Opaque" }
    17. //      Lighting On
    18.         Pass{
    19.             Tags { "LightMode" = "ForwardBase" }
    20.             CGPROGRAM
    21.             #pragma vertex Vert
    22.             #pragma fragment Frag
    23.             #include "UnityCG.cginc"
    24.                
    25.             uniform sampler2D _MainTex;
    26.             uniform sampler2D _NormalTex;
    27.             uniform sampler2D _ReflectTexPlane;
    28.             uniform float _SpecularShiness;
    29.             uniform float _ReflectRatio;
    30.             uniform float4 _lightSourcePos;
    31.             uniform float4 _LightColor0;
    32.            
    33.             uniform float4 _RimColor;
    34.             uniform float _RimPower;
    35.  
    36.            
    37.             struct VS_OUT
    38.             {
    39.            
    40.                 float4 pos:POSITION;
    41.                 float2 tex:TEXCOORD0;
    42.                 float3 light:TEXCOORD1;
    43. //              float3 view:TEXCOORD2;
    44.                 float3 worldPos:TEXCOORD2;
    45.                 float3 normal:TEXCOORD3;
    46.                
    47.             };
    48.            
    49.    
    50.          
    51.             VS_OUT Vert(appdata_full v)
    52.             {
    53.                 VS_OUT output;
    54.            
    55.                 output.pos = mul(UNITY_MATRIX_MVP,v.vertex);
    56.                
    57.                 output.tex = v.texcoord.xy;
    58.                
    59.                
    60.  
    61.                 output.worldPos = mul(_Object2World,v.vertex).xyz;
    62.                 //output.light = normalize(_lightSourcePos.xyz-worldPos);
    63. //              output.light = normalize(float3(0,6000,10000));
    64.                 output.light = normalize(float3(_WorldSpaceLightPos0));
    65.                
    66. //              output.light = normalize(float3(0,-1,0));
    67.                
    68.                
    69.                  //output.view = normalize(_cameraPos.xyz - worldPos);
    70.                  
    71. //                   output.view = normalize(_WorldSpaceCameraPos.xyz - worldPos);
    72. //                   output.view = _WorldSpaceCameraPos.xyz - worldPos;
    73.                  
    74. //                   output.normal = v.normal;
    75.                 output.normal = normalize(mul((float3x3)_World2Object, v.normal));
    76.                
    77.                  //output.light = normalize(mul((float3x3)_World2Object, output.light));
    78.                   //output.view= normalize(mul((float3x3)_World2Object, output.view));
    79.                  
    80. //                   output.view.z = -output.view.z;
    81.                  //output.worldPos = worldPos;
    82.                  
    83.                  //output.refl.xyz = normalize(mul((float3x3)_Object2World,v.normal));
    84.                  
    85.                  
    86.                  
    87.                 // float3 worldLightDir = normalize(( CameraWorldPos - mul(_Object2World,v.vertex)).xyz);
    88.                  //output.refl.w = saturate(dot(normalize(mul((float3x3)_Object2World,v.normal)),output.light));
    89.  
    90.  
    91.                 return output;
    92.             }
    93.                
    94.    
    95.             half4 Frag(float2 tex:TEXCOORD0,float3 light:TEXCOORD1,float3 worldPos:TEXCOORD2,float3 normal:TEXCOORD3):COLOR
    96.             {
    97.                 float3 view =  normalize( _WorldSpaceCameraPos.xyz - worldPos);
    98.                 float4 baseColor = tex2D(_MainTex,tex);
    99.                
    100.                 float3 normalTex = 2*tex2D(_NormalTex,tex)-1;
    101. //              float3 worldNormal = normalTex;
    102.                 float3 worldNormal = normalize(mul((float3x3)_Object2World,normalTex)).xyz;
    103. //              float3 worldNormal = normalize(mul(normalTex,(float3x3)_World2Object)).xyz;
    104.  
    105.                 float2 refl = (reflect(view,normal)).xz * 0.4 + 0.5;
    106. //              float2 refl = (reflect(view,worldNormal)).xz * 0.4 + 0.5;
    107.                 float4 reflectColor = tex2D(_ReflectTexPlane,refl);
    108.  
    109.                
    110.    
    111. //              float NdotH = clamp(dot(light,worldNormal),0,1);
    112. //             
    113. //              float fac =1+ pow(NdotH, _SpecularShiness);
    114.  
    115.                  float3 diffuseReflection = 4* float3(_LightColor0)* baseColor.xyz * max(0.2, dot(worldNormal, light));
    116.  
    117.  
    118.                
    119.                 float3 specularReflection = float3(1,1,1);
    120.                 float dotSpecular = dot( reflect(-light, worldNormal),  view);
    121.                 if (dot(worldNormal, light) < 0.0) {
    122.                    // light source on the wrong side?
    123.                
    124.                    specularReflection = float3(0.0, 0.0, 0.0);
    125.                       // no specular reflection
    126.                 }else{
    127.                     specularReflection = specularReflection*pow(max(0.0, dotSpecular), _SpecularShiness);
    128.                 }
    129.  
    130.                
    131.  
    132.                  
    133.                  float3 n = normal;
    134.                  n = mul((float3x3)_Object2World,n).xyz;
    135.                  
    136.                 half rim = 1.0 - saturate(dot (-view, n));
    137. //              half rim =  saturate(dot (-view, worldNormal));
    138.                
    139.                 float4 rimco =  _RimColor*pow (rim, _RimPower);
    140.                
    141.                
    142. //              baseColor += reflectColor * _ReflectRatio;
    143. //             
    144. //              baseColor+=rimco;
    145.                
    146.                
    147. //              return baseColor * (fac);
    148. //              baseColor.xyz*=dotSpecular;
    149. //              =specularReflection;
    150. //              return baseColor;
    151. //              return (diffuseReflection+specularReflection,1);
    152. //              return float4(diffuseReflection,1);
    153. //              return float4(specularReflection,1);
    154. //              return float4((worldNormal+1)*0.5,1);
    155.                 return float4(_World2Object[0][0],_World2Object[1][1],_World2Object[2][2],1);
    156.             }
    157.         ENDCG  
    158.         }  
    159.     }
    160.     FallBack "Diffuse"
    161. }
    162.  
    163.  
    Someone help me please!
     
  2. KuangZheng

    KuangZheng

    Joined:
    Feb 25, 2013
    Posts:
    75
    I find this promblem is relate to the structure of transform.
    the model's transform is like this:
    "JS" is the colored part
    $Screen Shot 2013-08-23 at 下午2.54.54.png


    "SJD_L" is left wing
    $Screen Shot 2013-08-23 at 下午2.57.05.png

    when I rotate or move plane in game,JS's color changed,but SJD_L's color is white.

    when I put the SJD_L out of transform "f4" like this and disable f4's gameobject:
    $Screen Shot 2013-08-23 at 下午3.01.51.png
    it's colored.

    But if I don't disable f4's gameobject, SJD_L is white again.
    $Screen Shot 2013-08-23 at 下午3.03.42.png

    Really don't know why this happened.
     

    Attached Files:

  3. Farfarer

    Farfarer

    Joined:
    Aug 17, 2010
    Posts:
    2,249
    If it's all the same material, do you have static or dynamic batching turned on? If so, disable those and see if it gives more reasonable results.

    I'm really not sure what you're trying to do though...

    Things like this make no sense. The normal is already in object space. You're now transforming it into something completely different.
    Code (csharp):
    1. output.normal = normalize(mul((float3x3)_World2Object, v.normal));
     
    forestrf likes this.
  4. KuangZheng

    KuangZheng

    Joined:
    Feb 25, 2013
    Posts:
    75
    Thanks,the normal transforming has same problem and I will replace it in the future. Now I disabled dynamic batching ,and it's works.
    $Screen Shot 2013-08-24 at 上午8.45.18.png

    It looks like that dynamic batching has some problem. The mesh of ‘JS’ has 1412 verts,1196 tris ,other mesh has low verts. I try to disable all of their gameobject and enable SJD_L,then I enable dynamic batching, it works.But when I enable
    one more gameobject,all of them become white again.
     
  5. KuangZheng

    KuangZheng

    Joined:
    Feb 25, 2013
    Posts:
    75
    I disabled all gameobjects and only enable the plane model (f4). There are 2 draw calls,one is the JS and another is all of other objects. All other object's meshes have 72 tris in all.But when I disable JS's gameobject, other object's are still white all the time.
     
  6. Dolkar

    Dolkar

    Joined:
    Jun 8, 2013
    Posts:
    576
    Is there still a difference between the two parts when you multiply the position by UNITY_MATRIX_MV instead? Note that this gets you view-space coordinates, so you might want to drop the view calculation in the fragment shader.
     
  7. KuangZheng

    KuangZheng

    Joined:
    Feb 25, 2013
    Posts:
    75
    Thanks.I multiply the position by UNITY_MATRIX_MV and multiply the position by UNITY_MATRIX_P,but the _World2Object of the parts which has problem is still not change when I rotate the model. I think my problem is why the _World2Object cannot change value when I rotate the model.

    However, I tried to add a C# script to "JS" gameObject with this code:
    Code (csharp):
    1.  
    2.                 renderer.sharedMaterial.SetMatrix( "localToWorldMatrix", renderer.localToWorldMatrix );
    3.         renderer.sharedMaterial.SetMatrix( "worldToLocalMatrix", renderer.worldToLocalMatrix );
    4.  
    In my shader I replace "_World2Object" to "worldToLocalMatrix" and "_Object2World" to localToWorldMatrix,it works. But I still feel confused why the _World2Object cannot work.