Search Unity

script to send collision data to shader ?

Discussion in 'Shaders' started by antislash, Jun 26, 2015.

  1. antislash

    antislash

    Joined:
    Apr 23, 2015
    Posts:
    646
    hello guys,
    i sware i browsed the forums for an answer, testes some codes, but all went with errors...

    could someone point me to a script for U5 that detects and sends colision data to a shader please?

    thanks mils
     
    Last edited: Jun 26, 2015
  2. antislash

    antislash

    Joined:
    Apr 23, 2015
    Posts:
    646
    i started with this code
    and it detects collision in playmode, i can print point values but the shader doesn't receive them

    Code (CSharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class VegetationCollision : MonoBehaviour {
    6.  
    7.     void OnCollisionEnter(Collision collisionInfo) {
    8.         ContactPoint contact = collisionInfo.contacts[0];
    9.         collisionInfo.gameObject.GetComponent<Renderer>().material.SetVector ("_CollisionPoint", contact.point);
    10.         collisionInfo.gameObject.GetComponent<Renderer>().material.SetVector ("_CollisionNormal", contact.normal);
    11.         Debug.DrawRay(contact.point, contact.normal, Color.white);
    12.         print (collisionInfo.gameObject.name+ "collided");
    13.         //print(collisionInfo.gameObject.name + " and " + collisionInfo.collider.name + " are still colliding");
    14.  
    15.  
    16.     }
    17. }
     
    Last edited: Jun 26, 2015
  3. antislash

    antislash

    Joined:
    Apr 23, 2015
    Posts:
    646
    and the shader i use.. just to detect point.., script detects collision
    but nothing happens, seems like nor value is passed from the script to the shader

    Code (CSharp):
    1.  Shader "Custom/detections/collision_detection" {
    2. Properties {
    3.         _CollisionPoint ("Collision point", Vector) = (0, 0, 0,1)
    4.         _CollisionNormal ("Collision normal", Vector) = (0, 0, 0,1)
    5.  
    6.         _Color ("Color (RGBA)", Color) = (0, 1, 0.5, 1)
    7.      }
    8.      SubShader {
    9.          Tags { "Queue" = "Transparent" "RenderType" = "Transparent" }
    10.          LOD 2000
    11.          Cull Back
    12.    
    13.          CGPROGRAM
    14.            #pragma surface surf Lambert vertex:vert alpha
    15.            #pragma target 3.0
    16.    
    17.           struct Input {
    18.              float3 worldPos;
    19.              float4 vertPos;
    20.            };
    21.    
    22.  
    23.            float4 _Color;
    24.            float4 _CollisionPoint, _CollisionNormal;
    25.            float4 localCollision;
    26.    
    27.            void vert (inout appdata_full v, out Input o)
    28.            {
    29.                 UNITY_INITIALIZE_OUTPUT(Input,o);
    30.                 o.vertPos = v.vertex;
    31.            }
    32.    
    33.            void surf (Input IN, inout SurfaceOutput o) {
    34.          
    35.             //localCollision = mul(_Object2World, IN.vertPos);
    36.             o.Albedo = _CollisionPoint.xyz;
    37.             o.Alpha=1;
    38.            }
    39.    
    40.            ENDCG
    41.      }
    42.      Fallback "Transparent/Diffuse"
    43. }
    44.  
     
    Last edited: Jun 28, 2015
  4. aubergine

    aubergine

    Joined:
    Sep 12, 2009
    Posts:
    2,880
    Just guessing;
    you should use sharedMaterial instead of material in your script
    and
    you should change the contactpoint vector to object space before sending it to the shader.

    Although it wont work as i guess you are trying to achieve some sort of shield effect but you will eventually see some colors on screen after you do the above.
     
  5. antislash

    antislash

    Joined:
    Apr 23, 2015
    Posts:
    646
    Hi aubergine,
    i tried sharedmaterial but nothing at all, same problem...
    what i am trying to do can be used for various things ie vegetation collision, surface effects etc.
    for now, i just want the color or the object to change so i'm sure to get the data.
    then i wil manage collision point and normal in shader, unless it's faster in script.

    could it be due to the fact that contact.point is a vector 3 ?
    (tried to replace contact point with new vector4 (x,y,z,1) and didn't work either)

    thanks for your help
     
    Last edited: Jun 29, 2015
  6. aubergine

    aubergine

    Joined:
    Sep 12, 2009
    Posts:
    2,880
    like i said, change the contact point vector to local space relative to the object.
    check the documents on transform.worldtolocalmatrix or inversetransformpoint.
     
  7. antislash

    antislash

    Joined:
    Apr 23, 2015
    Posts:
    646
    thanks aubergine, will do that and get back here
    thx mils

    edit : from the docs
    IMPORTANT: If you're setting shader parameters you MUST use Renderer.worldToLocalMatrix instead.
    i don't know yet how to code that but still working on this
     
    Last edited: Jun 29, 2015
  8. antislash

    antislash

    Joined:
    Apr 23, 2015
    Posts:
    646
    tried this, but nothing
    Code (CSharp):
    1.  
    2.  ContactPoint contact = collisionInfo.contacts[0];
    3.  Renderer rend = collisionInfo.gameObject.GetComponent<Renderer>();
    4.  Vector4 localPoint = rend.worldToLocalMatrix.MultiplyPoint (contact.point);
    5.  rend.material.SetVector("_CollisionPoint", localPoint);
    6.  
     
    Last edited: Jun 29, 2015
  9. aubergine

    aubergine

    Joined:
    Sep 12, 2009
    Posts:
    2,880
    I cant write code as i am selling something smiliar as a commercial asset.
    However, here is some psuedo on how you can do it:

    script:
    if(object is hit somehow) get hit position vector
    shader.sharedmaterial.setVector( "_Collision0", object.transform.inversetransformpoint(hit.position) )

    shader:
    vert() {
    distance = v.vertex.xyz - transformedhitpoint.xyz; //probably normalized
    }
    frag() {
    do some fancy stuff with the distance value
    }

    Next, you will want to send an array of hit point(s) as well as some array of timer(s) to the shader in order to get a nice shield effect.
     
  10. antislash

    antislash

    Joined:
    Apr 23, 2015
    Posts:
    646
    hey aubergine thanks a lot mate, that's great, will test it asap
    i'll help you back if i can
    cheers

    edit : that's not for a shield effect, more for surface effects (dust, bullets etc)
     
    Last edited: Jun 30, 2015
  11. aubergine

    aubergine

    Joined:
    Sep 12, 2009
    Posts:
    2,880
    Same principle applies, anyways if you are still having trouble, you should check this package.
     
  12. Hugoliv

    Hugoliv

    Joined:
    Dec 8, 2017
    Posts:
    5
    Hey @antislash, Did you able to figure it out ?