просто интересно, если кто-нибудь может протянуть руку, провел часы до сих пор по этому поводу:Unity Shader нормалей неправильно
Кто-нибудь знает, почему это происходит ??? Когда я двигаюсь, дно всегда ярче верхнего.
основной поток верт: * получить точку, что + X и точка, + Z для использования в поперечном умножении позже, чтобы получить нормальный
* перевести эти точки в мировом пространстве, так что я могу ищу obsticals в реальном пространстве
* фигура из оси у смещения для нашей точки + дополнительных услуг, сделанных на первом этапе для кросса
* значение объекта приращения пространства пути перемещения
* найти новое нормальный используя перекрестную
* установить нормальный
* множество вершин.
То, что я думаю, что происходит в том, что нормали на неверной оси ... любая помощь apreciated
Shader "Custom/ExtrudePointArray" {
Properties {
_Color ("Color", Color) = (1,1,1,1)
_MainTex ("Albedo (RGB)", 2D) = "white" {}
_Glossiness("Smoothness", Range(0,1)) = 0.5
_Metallic("Metallic", Range(0,1)) = 0.0
//water stuff
_Scale("Scale", float) = 1
_Speed("Speed", float) = 1
_Frequency("Frequency", float) = 1
// wave maker
_Height("_Height", float) = 1.0
_Extrude_Close("_Extrude_Close", float) = 3.0
[HideInInspector]_ExtrudePointCount("_ExtrudePointCount", int) = 0
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 200
CGPROGRAM
// Physically based Standard lighting model, and enable shadows on all light types
#pragma surface surf Standard fullforwardshadows vertex:vert
//debug normals
//#pragma surface surf Standard fullforwardshadows vertex:vert finalcolor:showNormals
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 4.0
sampler2D _MainTex;
struct Input {
float2 uv_MainTex;
float3 newNormal;
half3 debugColor;
};
half _Glossiness;
half _Metallic;
fixed4 _Color;
// water stuff
float _Scale, _Speed, _Frequency;
float _Extrude_Close, _Height;
uniform float _ExtrudePointX[20], _ExtrudePointZ[20], _ExtrudePointCount;
float calcWaveHeight(float2 worvldLoc) {
//disruption
half offsetvertDis = ((worvldLoc.x * worvldLoc.x) + (worvldLoc.y * worvldLoc.y));
half valueDis = _Scale * sin(_Time.w * _Speed + offsetvertDis * _Frequency*1000);
// diag wave
half offsetvertDiag = worvldLoc.x +worvldLoc.y;
half valueDiag = _Scale * sin(_Time.w * _Speed * _Frequency + offsetvertDiag);
return valueDis + valueDiag;
}
float calcDistFromPoint(float2 worldLoc, float2 pointToCheck) {
float closePercent = 0;
float dist = abs(distance(worldLoc, pointToCheck));
if (dist < _Extrude_Close) {
closePercent = (_Extrude_Close - dist/_Extrude_Close);
}
return closePercent;
}
float calcVertNewPos(float3 worldLoc) {
float highestPos = 0;
float2 worldLocHor = float2(worldLoc.x, worldLoc.z);
for (int i = 0; i < _ExtrudePointCount; i++) {
float2 boxPos = float2(_ExtrudePointX[i], _ExtrudePointZ[i]);
float newPos = calcDistFromPoint(worldLocHor, boxPos) * _Height;
// the value returned is a float so don't check for zero, check that it's not above zero
if (newPos < 0.001) {
newPos = calcWaveHeight(worldLocHor);
}
if (newPos > highestPos) {
highestPos = newPos;
}
//highestPos = worldLoc.x * i;
}
return highestPos;
}
void vert(inout appdata_full v, out Input o)
{
UNITY_INITIALIZE_OUTPUT(Input, o);
float3 v0 = v.vertex.xyz;
float3 v1 = v0 + float3(0.05, 0, 0); // +X
float3 v2 = v0 + float3(0, 0, 0.05); // +Z
float3 w0 = mul(unity_ObjectToWorld, v.vertex).xyz;
float3 w1 = w0 + float3(0.05, 0, 0); // +X
float3 w2 = w0 + float3(0, 0, 0.05); // +Z
float h0 = calcVertNewPos(w0);
float h1 = calcVertNewPos(w1);
float h2 = calcVertNewPos(w2);
v0.y = h0;
v1.y = h1;
v2.y = h2;
float3 vna = cross(v2 - v0, v1 - v0);
// debug
//o.debugColor = (normalize(v0) * 0.5) + 0.5;
//o.debugColor = (normalize(v.vertex.xyz) * 0.5) + 0.5;
//o.debugColor = (normalize(vna) * 0.5) + 0.5;
// Put normals back in object space
//float3x3 worlspace = float3x3(unity_WorldToObject.xyz);
v.normal = normalize(vna);
o.newNormal = v.normal;
v.vertex.xyz = v0;
}
void showNormals(Input IN, SurfaceOutputStandard o, inout fixed4 color) {
color.rgb = IN.debugColor.rgb;
color.a = 1;
}
void surf (Input IN, inout SurfaceOutputStandard o) {
// Albedo comes from a texture tinted by color
fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
o.Albedo = c.rgb;
// Metallic and smoothness come from slider variables
o.Metallic = _Metallic;
o.Smoothness = _Glossiness;
o.Alpha = c.a;
o.Normal = IN.newNormal;
}
ENDCG
}
FallBack "Diffuse"
}
Я знаю, что я почти наверняка делает Somthing неправильно reguarding нормального расчета. Но я не могу найти на нем никаких хороших ресурсов, и единственное, что я нашел: https://www.youtube.com/watch?v=1G37-Yav2ZM был написан для более ранней версии шейдерного языка, и сайт для загрузки источника теперь вредоносный :(Это убивает меня
Также здесь код, который работает выдавливание точек затенения, если вам это нужно:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ExtrudePoint : MonoBehaviour {
public GameObject[] Waves;
private Renderer _renderer;
// Use this for initialization
void Start()
{
if (Waves == null || Waves.Length > 8)
{
throw new Exception("Max of 8 waves, min of 1");
}
_renderer = GetComponent<Renderer>();
}
// Update is called once per frame
void Update()
{
int totWaves = 0;
// probably slow
var floatArrayX = new float[Waves.Length];
var floatArrayZ = new float[Waves.Length];
for (var i = 0; i < Waves.Length; i++)
{
var wave = Waves[i];
if (wave != null)
{
totWaves++;
floatArrayX[totWaves - 1] = wave.gameObject.transform.position.x;
floatArrayZ[totWaves - 1] = wave.gameObject.transform.position.z;
//_renderer.material.SetFloat(WavePointExtruderConstants._ExtrudePointX, wave.gameObject.transform.position.x);
//_renderer.material.SetFloat(WavePointExtruderConstants._ExtrudePointZ, wave.gameObject.transform.position.z);
//Debug.Log(wave.gameObject.transform.position);
}
}
// probably slow
var xWaveArray = new float[totWaves];
var zWaveArray = new float[totWaves];
for(int i = 0; i < totWaves; i++)
{
xWaveArray[i] = floatArrayX[i];
zWaveArray[i] = floatArrayZ[i];
}
//Debug.Log(totWaves);
_renderer.material.SetFloatArray(WavePointExtruderConstants._ExtrudePointX, xWaveArray);
_renderer.material.SetFloatArray(WavePointExtruderConstants._ExtrudePointZ, zWaveArray);
_renderer.material.SetFloat(WavePointExtruderConstants._ExtrudePointCount, totWaves);
}
}
public static class WavePointExtruderConstants
{
public static string _Extrude_Close = "_Extrude_Close";
public static string _ExtrudePointX = "_ExtrudePointX";
public static string _ExtrudePointZ = "_ExtrudePointZ";
public static string _ExtrudePointCount = "_ExtrudePointCount";
}
установка представляет собой равнину с шейдерным материалом + кодом выше. Затем вы производите любой игровой объект и помещаете его в массив Waves.
даст вам возможность, когда я смогу! благодаря –