Search Unity

Shading is screenspace for some reason :(

Discussion in 'Shaders' started by ausiemick, Jan 21, 2017.

  1. ausiemick

    ausiemick

    Joined:
    Oct 8, 2012
    Posts:
    20
    upload_2017-1-21_18-41-44.png

    Does anyone know why this is happening??? as I move along, the bottom is always brighter than the top.

    the basic flow of the vert:
    *get point that is +X and a point that is +Z for use in cross multiplication later to get normal
    *translate those points to world space so that I may look for obsticals in real space
    *figure out the y axis displacement for our point + the extras made in step one for cross
    *increment object space values by displacement
    *find new normal using cross
    *set normal
    *set vertex.

    What I think is happening is that the normals are on the wrong axis... any help apreciated

    upload_2017-1-21_19-6-54.png

    Code (CSharp):
    1. Shader "Custom/ExtrudePointArray" {
    2.     Properties {
    3.         _Color ("Color", Color) = (1,1,1,1)
    4.         _MainTex ("Albedo (RGB)", 2D) = "white" {}
    5.         _Glossiness("Smoothness", Range(0,1)) = 0.5
    6.         _Metallic("Metallic", Range(0,1)) = 0.0
    7.  
    8.             //water stuff
    9.             _Scale("Scale", float) = 1
    10.             _Speed("Speed", float) = 1
    11.             _Frequency("Frequency", float) = 1
    12.  
    13.             // wave maker
    14.             _Height("_Height", float) = 1.0
    15.             _Extrude_Close("_Extrude_Close", float) = 3.0
    16.  
    17.             [HideInInspector]_ExtrudePointCount("_ExtrudePointCount", int) = 0
    18.     }
    19.     SubShader {
    20.         Tags { "RenderType"="Opaque" }
    21.         LOD 200
    22.      
    23.         CGPROGRAM
    24.         // Physically based Standard lighting model, and enable shadows on all light types
    25. #pragma surface surf Standard fullforwardshadows  vertex:vert
    26.  
    27.         //debug normals
    28. //#pragma surface surf Standard fullforwardshadows  vertex:vert finalcolor:showNormals
    29.  
    30.         // Use shader model 3.0 target, to get nicer looking lighting
    31.         #pragma target 4.0
    32.  
    33.         sampler2D _MainTex;
    34.  
    35.         struct Input {
    36.             float2 uv_MainTex;
    37.             float3 newNormal;
    38.             half3 debugColor;
    39.         };
    40.  
    41.         half _Glossiness;
    42.         half _Metallic;
    43.         fixed4 _Color;
    44.  
    45.         // water stuff
    46.         float _Scale, _Speed, _Frequency;
    47.  
    48.  
    49.         float _Extrude_Close, _Height;
    50.         uniform float _ExtrudePointX[20], _ExtrudePointZ[20], _ExtrudePointCount;
    51.  
    52.         float calcWaveHeight(float2 worvldLoc) {
    53.             //disruption
    54.             half offsetvertDis = ((worvldLoc.x * worvldLoc.x) + (worvldLoc.y * worvldLoc.y));
    55.             half valueDis = _Scale * sin(_Time.w * _Speed + offsetvertDis * _Frequency*1000);
    56.             // diag wave
    57.             half offsetvertDiag =  worvldLoc.x +worvldLoc.y;
    58.             half valueDiag = _Scale * sin(_Time.w * _Speed * _Frequency + offsetvertDiag);
    59.  
    60.             return valueDis + valueDiag;
    61.         }
    62.  
    63.         float calcDistFromPoint(float2 worldLoc, float2 pointToCheck) {
    64.             float closePercent = 0;
    65.             float dist = abs(distance(worldLoc, pointToCheck));
    66.  
    67.             if (dist < _Extrude_Close) {
    68.                 closePercent = (_Extrude_Close - dist / _Extrude_Close);
    69.             }
    70.             return closePercent;
    71.         }
    72.  
    73.         float calcVertNewPos(float3 worldLoc) {
    74.             float highestPos = 0;
    75.             float2 worldLocHor = float2(worldLoc.x, worldLoc.z);
    76.  
    77.             for (int i = 0; i < _ExtrudePointCount; i++) {
    78.                 float2 boxPos = float2(_ExtrudePointX[i], _ExtrudePointZ[i]);
    79.  
    80.                 float newPos = calcDistFromPoint(worldLocHor, boxPos) * _Height;
    81.  
    82.                 // the value returned is a float so don't check for zero, check that it's not above zero
    83.                 if (newPos < 0.001) {
    84.                     newPos = calcWaveHeight(worldLocHor);
    85.                 }
    86.  
    87.                 if (newPos > highestPos) {
    88.                     highestPos = newPos;
    89.                 }
    90.                 //highestPos = worldLoc.x * i;
    91.             }
    92.  
    93.             return highestPos;
    94.         }
    95.  
    96.         void vert(inout appdata_full v, out Input o)
    97.         {
    98.             UNITY_INITIALIZE_OUTPUT(Input, o);
    99.  
    100.             float3 v0 = v.vertex.xyz;
    101.             float3 v1 = v0 + float3(0.05, 0, 0); // +X
    102.             float3 v2 = v0 + float3(0, 0, 0.05); // +Z
    103.  
    104.             float3 w0 = mul(unity_ObjectToWorld, v.vertex).xyz;
    105.             float3 w1 = w0 + float3(0.05, 0, 0); // +X
    106.             float3 w2 = w0 + float3(0, 0, 0.05); // +Z
    107.  
    108.             float h0 = calcVertNewPos(w0);
    109.             float h1 = calcVertNewPos(w1);
    110.             float h2 = calcVertNewPos(w2);
    111.  
    112.             v0.y = h0;
    113.             v1.y = h1;
    114.             v2.y = h2;
    115.  
    116.             float3 vna = cross(v2 - v0, v1 - v0);
    117.  
    118.             // debug
    119.             //o.debugColor = (normalize(v0) * 0.5) + 0.5;
    120.             //o.debugColor = (normalize(v.vertex.xyz) * 0.5) + 0.5;
    121.             //o.debugColor = (normalize(vna) * 0.5) + 0.5;
    122.  
    123.             // Put normals back in object space
    124.             //float3x3 worlspace = float3x3(unity_WorldToObject.xyz);
    125.  
    126.             v.normal = normalize(vna);
    127.             o.newNormal = v.normal;
    128.  
    129.             v.vertex.xyz = v0;
    130.         }
    131.  
    132.         void showNormals(Input IN, SurfaceOutputStandard o, inout fixed4 color) {
    133.             color.rgb = IN.debugColor.rgb;
    134.             color.a = 1;
    135.         }
    136.  
    137.         void surf (Input IN, inout SurfaceOutputStandard o) {
    138.             // Albedo comes from a texture tinted by color
    139.             fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
    140.             o.Albedo = c.rgb;
    141.             // Metallic and smoothness come from slider variables
    142.             o.Metallic = _Metallic;
    143.             o.Smoothness = _Glossiness;
    144.             o.Alpha = c.a;
    145.             o.Normal = IN.newNormal;
    146.         }
    147.         ENDCG
    148.     }
    149.     FallBack "Diffuse"
    150. }
    151.  
    I know I'm almost certainly doing somthing wrong reguarding normal calculation.. But I can't find any good resources on it and the only thing I did find:
    was written for an earlier version of the shader language and the site to download source is malware now :( This is killing me

    Also here's the code that runs the shader's extrude points if you need it:


    Code (CSharp):
    1. using System;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5.  
    6. public class ExtrudePoint : MonoBehaviour {
    7.  
    8.     public GameObject[] Waves;
    9.     private Renderer _renderer;
    10.  
    11.     // Use this for initialization
    12.     void Start()
    13.     {
    14.         if (Waves == null || Waves.Length > 8)
    15.         {
    16.             throw new Exception("Max of 8 waves, min of 1");
    17.         }
    18.  
    19.         _renderer = GetComponent<Renderer>();
    20.  
    21.     }
    22.  
    23.     // Update is called once per frame
    24.     void Update()
    25.     {
    26.         int totWaves = 0;
    27.         // probably slow
    28.         var floatArrayX = new float[Waves.Length];
    29.         var floatArrayZ = new float[Waves.Length];
    30.         for (var i = 0; i < Waves.Length; i++)
    31.         {
    32.             var wave = Waves[i];
    33.             if (wave != null)
    34.             {
    35.                 totWaves++;
    36.                 floatArrayX[totWaves - 1] = wave.gameObject.transform.position.x;
    37.                 floatArrayZ[totWaves - 1] = wave.gameObject.transform.position.z;
    38.                 //_renderer.material.SetFloat(WavePointExtruderConstants._ExtrudePointX, wave.gameObject.transform.position.x);
    39.                 //_renderer.material.SetFloat(WavePointExtruderConstants._ExtrudePointZ, wave.gameObject.transform.position.z);
    40.  
    41.                 //Debug.Log(wave.gameObject.transform.position);
    42.             }
    43.         }
    44.  
    45.         // probably slow
    46.         var xWaveArray = new float[totWaves];
    47.         var zWaveArray = new float[totWaves];
    48.  
    49.         for(int i = 0; i < totWaves; i++)
    50.         {
    51.             xWaveArray[i] = floatArrayX[i];
    52.             zWaveArray[i] = floatArrayZ[i];
    53.         }
    54.  
    55.         //Debug.Log(totWaves);
    56.  
    57.         _renderer.material.SetFloatArray(WavePointExtruderConstants._ExtrudePointX, xWaveArray);
    58.         _renderer.material.SetFloatArray(WavePointExtruderConstants._ExtrudePointZ, zWaveArray);
    59.         _renderer.material.SetFloat(WavePointExtruderConstants._ExtrudePointCount, totWaves);
    60.     }
    61. }
    62.  
    63. public static class WavePointExtruderConstants
    64. {
    65.     public static string _Extrude_Close = "_Extrude_Close";
    66.     public static string _ExtrudePointX = "_ExtrudePointX";
    67.     public static string _ExtrudePointZ = "_ExtrudePointZ";
    68.     public static string _ExtrudePointCount = "_ExtrudePointCount";
    69. }
    70.  
    the setup is a plain with the shader material + code above. You then make any gameobject and place it into the scripts Waves array.
     
    Last edited: Jan 21, 2017
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    The normal output that the surface shader is expecting is one in tangent space. Try just commenting out that line.
     
  3. ausiemick

    ausiemick

    Joined:
    Oct 8, 2012
    Posts:
    20
    Sorry what line :( been working on this for 8 hours now so brain not working
     
  4. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    o.Normal = IN.newNormal;

    You're already setting the new normals on the vertex properties (which really should be in object space). Setting the same data later in the surf function isn't going to do what you want.
     
  5. ausiemick

    ausiemick

    Joined:
    Oct 8, 2012
    Posts:
    20
    Oh yes,

    I had to do that because in a prevous shader I wrote, the normal couldn't be set inside of the vert, it had to be done in the surf. When I can get back on the PC (it's borrowed and I locked it :|) I'll just remove the extra. Don't think that will fix though :\ feel like I need a physics degree for this crap
     
  6. ausiemick

    ausiemick

    Joined:
    Oct 8, 2012
    Posts:
    20
    Thanks for the reply though bgolus!