Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/unity3d/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Unity3d 接收和投射阴影(自定义几何体草着色器)-Unity C#_Unity3d_Shader_Vertex Shader_Cg_Geometry Shader - Fatal编程技术网

Unity3d 接收和投射阴影(自定义几何体草着色器)-Unity C#

Unity3d 接收和投射阴影(自定义几何体草着色器)-Unity C#,unity3d,shader,vertex-shader,cg,geometry-shader,Unity3d,Shader,Vertex Shader,Cg,Geometry Shader,我在学习Sam Wronski aka制作的教程。零的世界(),他为点云草生成器编写了一个几何体着色器。很好的教程,但我想知道(经过几天的研究后没有找到合适的解决方案)如何在着色器中实现阴影(投射和接收阴影)。我正试图深入挖掘着色器,但这对我来说还是一个很高的水平 我的问题是:如何实现此草地着色器的阴影投射和接收?目前存在并运行良好的代码如下: Shader "Custom/GrassGeometryShader" { // https://www.youtube.com/watch?

我在学习Sam Wronski aka制作的教程。零的世界(),他为点云草生成器编写了一个几何体着色器。很好的教程,但我想知道(经过几天的研究后没有找到合适的解决方案)如何在着色器中实现阴影(投射和接收阴影)。我正试图深入挖掘着色器,但这对我来说还是一个很高的水平

我的问题是:如何实现此草地着色器的阴影投射和接收?目前存在并运行良好的代码如下:

Shader "Custom/GrassGeometryShader" {

    // https://www.youtube.com/watch?v=HY6qFbmbij8 und http://www.battlemaze.com/?p=153

    Properties {
    // --> HDR allows High Dynamic Colors
        [HDR]_BackgroundColor ("Background Color", Color) = (1,0,0,1) // default to red
        [HDR]_ForegroundColor ("Foreground Color", Color) = (0,1,0,1) // default to green 
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _Glossiness ("Smoothness", Range(0,1)) = 0.5
        _Metallic ("Metallic", Range(0,1)) = 0.0
        _Cutoff("Alpha Cuttoff", Range (0,1)) = 0.15 // Wieviel abgeschnitten sien soll
        _GrassHeight("GrasHeight", Float) = 0.25
        _GrassWidt("GrasWidth", Float) = 0.25
        _WindSpeed ("WindSpeed", Float) = 100
        _WindStrength("WindStrength", Float) = 0.05
    }
    SubShader {
        Tags { "RenderType"="Opaque" }
        LOD 200

        Pass
        {

        Cull OFF 
        CGPROGRAM
        #include "UnityCG.cginc" // like: "using" in C# 
        // Vertex-Shader with vert-function
        #pragma vertex vert
        // Fragment-Shader with frag-function
        #pragma fragment frag
        // Geometry-Shader with geom-function 
        #pragma geometry geom

        // Use shader model 3.0 target, to get nicer looking lighting
        #pragma target 4.0 // needs to be 4.0 !

        sampler2D _MainTex;

        // vertex to graphics (v2g)
        struct v2g 
        {
            float4  pos : SV_POSITION;
            float3  norm : NORMAL;
            float2  uv : TEXCOORD0;
            float3 color : TEXCOORD1;
        };

        //graphics to fragments (g2f)
        struct g2f 
        {
            float4  pos : SV_POSITION;
            float3  norm : NORMAL;
            float2  uv : TEXCOORD0;            
            float3 diffuseColor : TEXCOORD1;
            //float3 specularColor : TEXCOORD2;
        };

        half _Glossiness;
        half _Metallic;
        fixed4 _BackgroundColor;
        fixed4 _ForegroundColor;
        half _GrassHeight;
        half _GrassWidth;
        half _Cutoff;
        half _WindStrength;
        half _WindSpeed;

        // Vertex-Shader from Battlemaze.com
        v2g vert(appdata_full v)
        {
            float3 v0 = mul(unity_ObjectToWorld, v.vertex).xyz;

            v2g OUT;
            OUT.pos = v.vertex;
            OUT.norm = v.normal;
            OUT.uv = v.texcoord;
            OUT.color = tex2Dlod(_MainTex, v.texcoord).rgb;
            return OUT;         
        }

        void buldQuad(inout TriangleStream<g2f> triStream, float3 points[4], float3 color) {
            g2f OUT;
            float3 faceNormal = cross(points[1]-points[0], points[2]-points[0]);
            for(int i; i < 4; ++i) {
            OUT.pos = UnityObjectToClipPos(points[i]);
            OUT.norm = faceNormal;
            OUT.diffuseColor = color;
            OUT.uv = float2(i%2, (int)i/2);
            triStream.Append(OUT);
            }
            triStream.RestartStrip();
        }

        // geom-Funktion
        [maxvertexcount(24)]
        void geom(point v2g IN[1], inout TriangleStream<g2f> triStream)
        {
            float3 lightPosition = _WorldSpaceLightPos0;

            float3 perpendicularAngle = float3(0,0,1);
            float3 faceNormal = cross(perpendicularAngle, IN[0].norm); // normal of gras

            float3 v0 = IN[0].pos.xyz; // Tip of the gras
            float3 v1 = IN[0].pos.xyz + IN[0].norm * _GrassHeight; // base of the gras
            float3 v2 = IN[0].pos.xyz + IN[0].norm * _GrassHeight / 2; // middle part (?)

            float3 wind = float3(sin(_Time.x * _WindSpeed + v0.x) + sin(_Time.x * _WindSpeed + v0.z * 2), 0, cos(_Time.x * _WindSpeed + v0.x * 2) + cos(_Time.x * _WindSpeed + v0.z)); // Anzahl oder Stärke der Manipulation an den Eckpunkten 
            // (_Time.x + v0.x + v0.z looks "random", because it's using time + coordinates)

            v1 += wind * _WindStrength;
            v2 += (wind * _WindStrength/2)/2;

            float3 color = (IN[0].color); // color of the gras

            float sin30 = 0.5;
            float sin60 = 0.866f;
            float cos30 = sin60;
            float cos60 = sin30;

            g2f OUT;

            // Quad 1 - the following code could fit in one function (BUT!) it did not work on MacOSX, that's why it's still calculated the long way

        OUT.pos = UnityObjectToClipPos(v0 + perpendicularAngle * 0.5 * _GrassHeight);
        OUT.norm = faceNormal;
        OUT.diffuseColor = color;
        OUT.uv = float2(1, 0);
        triStream.Append(OUT);


        OUT.pos = UnityObjectToClipPos(v1 + perpendicularAngle * 0.5 * _GrassHeight);
        OUT.norm = faceNormal;
        OUT.diffuseColor = color;
        OUT.uv = float2(1, 1);
        triStream.Append(OUT);

        OUT.pos = UnityObjectToClipPos(v0);
        OUT.norm = faceNormal;
        OUT.diffuseColor = color;
        OUT.uv = float2(0.5, 0);
        triStream.Append(OUT);

        OUT.pos = UnityObjectToClipPos(v1);
        OUT.norm = faceNormal;
        OUT.diffuseColor = color;
        OUT.uv = float2(0.5, 1);
        triStream.Append(OUT);

        OUT.pos = UnityObjectToClipPos(v1 - perpendicularAngle * 0.5 * _GrassHeight);
        OUT.norm = faceNormal;
        OUT.diffuseColor = color;
        OUT.uv = float2(0, 1);
        triStream.Append(OUT);

        OUT.pos = UnityObjectToClipPos(v0 - perpendicularAngle * 0.5 * _GrassHeight);
        OUT.norm = faceNormal;
        OUT.diffuseColor = color;
        OUT.uv = float2(0, 0);
        triStream.Append(OUT);

        OUT.pos = UnityObjectToClipPos(v0);
        OUT.norm = faceNormal;
        OUT.diffuseColor = color;
        OUT.uv = float2(0.5, 0);
        triStream.Append(OUT);

        OUT.pos = UnityObjectToClipPos(v1);
        OUT.norm = faceNormal;
        OUT.diffuseColor = color;
        OUT.uv = float2(0.5, 1);
        triStream.Append(OUT);

        // Quad 2

        OUT.pos = UnityObjectToClipPos(v0 + float3(sin60, 0, -cos60) * 0.5 * _GrassHeight);
        OUT.norm = faceNormal;
        OUT.diffuseColor = color;
        OUT.uv = float2(1, 0);
        triStream.Append(OUT);

        OUT.pos = UnityObjectToClipPos(v1 + float3(sin60, 0, -cos60)* 0.5 * _GrassHeight);
        OUT.norm = faceNormal;
        OUT.diffuseColor = color;
        OUT.uv = float2(1, 1);
        triStream.Append(OUT);

        OUT.pos = UnityObjectToClipPos(v0);
        OUT.norm = faceNormal;
        OUT.diffuseColor = color;
        OUT.uv = float2(0.5, 0);
        triStream.Append(OUT);

        OUT.pos = UnityObjectToClipPos(v1);
        OUT.norm = faceNormal;
        OUT.diffuseColor = color;
        OUT.uv = float2(0.5, 1);
        triStream.Append(OUT);

        OUT.pos = UnityObjectToClipPos(v0 - float3(sin60, 0, -cos60) * 0.5 * _GrassHeight);
        OUT.norm = faceNormal;
        OUT.diffuseColor = color;
        OUT.uv = float2(0, 0);
        triStream.Append(OUT);

        OUT.pos = UnityObjectToClipPos(v1 - float3(sin60, 0, -cos60) * 0.5 * _GrassHeight);
        OUT.norm = faceNormal;
        OUT.diffuseColor = color;
        OUT.uv = float2(0, 1);
        triStream.Append(OUT);

        OUT.pos = UnityObjectToClipPos(v0);
        OUT.norm = faceNormal;
        OUT.diffuseColor = color;
        OUT.uv = float2(0.5, 0);
        triStream.Append(OUT);

        OUT.pos = UnityObjectToClipPos(v1);
        OUT.norm = faceNormal;
        OUT.diffuseColor = color;
        OUT.uv = float2(0.5, 1);
        triStream.Append(OUT);

        // Quad 3 - Positive

        OUT.pos = UnityObjectToClipPos(v0 + float3(sin60, 0, cos60) * 0.5 * _GrassHeight);
        OUT.norm = faceNormal;
        OUT.diffuseColor = color;
        OUT.uv = float2(1, 0);
        triStream.Append(OUT);

        OUT.pos = UnityObjectToClipPos(v1 + float3(sin60, 0, cos60)* 0.5 * _GrassHeight);
        OUT.norm = faceNormal;
        OUT.diffuseColor = color;
        OUT.uv = float2(1, 1);
        triStream.Append(OUT);

        OUT.pos = UnityObjectToClipPos(v0);
        OUT.norm = faceNormal;
        OUT.diffuseColor = color;
        OUT.uv = float2(0.5, 0);
        triStream.Append(OUT);

        OUT.pos = UnityObjectToClipPos(v1);
        OUT.norm = faceNormal;
        OUT.diffuseColor = color;
        OUT.uv = float2(0.5, 1);
        triStream.Append(OUT);

        OUT.pos = UnityObjectToClipPos(v0 - float3(sin60, 0, cos60) * 0.5 * _GrassHeight);
        OUT.norm = faceNormal;
        OUT.diffuseColor = color;
        OUT.uv = float2(0, 0);
        triStream.Append(OUT);

        OUT.pos = UnityObjectToClipPos(v1 - float3(sin60, 0, cos60) * 0.5 * _GrassHeight);
        OUT.norm = faceNormal;
        OUT.diffuseColor = color;
        OUT.uv = float2(0, 1);
        triStream.Append(OUT);

        OUT.pos = UnityObjectToClipPos(v0);
        OUT.norm = faceNormal;
        OUT.diffuseColor = color;
        OUT.uv = float2(0.5, 0);
        triStream.Append(OUT);

        OUT.pos = UnityObjectToClipPos(v1);
        OUT.norm = faceNormal;
        OUT.diffuseColor = color;
        OUT.uv = float2(0.5, 1);
        triStream.Append(OUT);

        }

        // Fragment-Shader by Battlemaze.com --> gets input v2g and renders it on screen
        half4 frag(g2f IN) : COLOR
        {
            fixed4 c = tex2D(_MainTex, IN.uv);
            clip(c.a - _Cutoff);
            return c;
            //return float4 (IN.diffuseColor.rgb, 1.0);
        }

        ENDCG
        }
    }
}
着色器“自定义/GrassGeometryShader”{
// https://www.youtube.com/watch?v=HY6qFbmbij8 undhttp://www.battlemaze.com/?p=153
性质{
//-->HDR允许高动态颜色
[HDR]_BackgroundColor(“背景色”,Color)=(1,0,0,1)//默认为红色
[HDR]_ForegroundColor(“前景色”,颜色)=(0,1,0,1)//默认为绿色
_MainTex(“反照率(RGB)”,2D)=“白色”{}
_光泽度(“平滑度”,范围(0,1))=0.5
_金属(“金属”,范围(0,1))=0.0
_截止点(“阿尔法截止点”,范围(0,1))=0.15//Wieviel abgeschnitten sien soll
_草高(“草高”,浮动)=0.25
_格拉斯威特(“格拉斯威特”,浮动)=0.25
_风速(“风速”,浮动)=100
_风力(“风力”,浮动)=0.05
}
子阴影{
标记{“RenderType”=“不透明”}
LOD 200
通过
{
剔除
CGP程序
#在C#中包括“UnityCG.cginc”//like:“using”
//具有vert函数的顶点着色器
#pragma顶点顶点
//带有frag函数的片段着色器
#布拉格碎片碎片
//具有geom函数的几何体着色器
#布拉格几何几何
//使用着色器模型3.0目标,以获得更好的照明效果
#pragma目标4.0//必须是4.0!
取样器2D_MainTex;
//顶点到图形(v2g)
结构v2g
{
浮动4位置:SV_位置;
3常模:正常;
float2uv:TEXCOORD0;
float3颜色:TEXCOORD1;
};
//碎片图形(g2f)
结构g2f
{
浮动4位置:SV_位置;
3常模:正常;
float2uv:TEXCOORD0;
float3漫射色:TEXCOORD1;
//float3镜面颜色:TEXCOORD2;
};
半光泽度;
半金属;
固定4_背景色;
固定4_前底色;
半高;
半宽;
半切;
一半风力;
半风速;
//来自Battlemaze.com的顶点着色器
v2g垂直(appdata_全v)
{
float3 v0=mul(unity_ObjectToWorld,v.vertex).xyz;
v2g输出;
OUT.pos=v.顶点;
OUT.norm=v.normal;
OUT.uv=v.texcoord;
OUT.color=tex2Dlod(_MainTex,v.texcoord).rgb;
返回;
}
void buldQuad(无三角形流三流,浮动3点[4],浮动3颜色){
g2f输出;
float3 faceNormal=交叉(点[1]-点[0],点[2]-点[0]);
对于(int i;i<4;++i){
OUT.pos=单位对象到lippos(点[i]);
OUT.norm=faceNormal;
OUT.diffuseColor=颜色;
OUT.uv=float2(i%2,(int)i/2);
追加(输出);
}
triStream.RestartStrip();
}
//几何函数
[maxvertexcount(24)]
空隙几何(点v2g在[1]中,在非三角流三流中)
{
float3 lightPosition=_WorldSpaceLightPos0;
浮动3垂直角=浮动3(0,0,1);
float3 faceNormal=交叉(垂直角,在[0]中)。norm);//gras的法线
float3 v0=IN[0]。pos.xyz;//GRA的尖端
float3 v1=IN[0]。pos.xyz+IN[0]。norm*\u grashheight;//gras的底部
float3 v2=IN[0]。pos.xyz+IN[0]。norm*\u grashheight/2;//中间部分(?)
float3风=float3(sin(_-Time.x*_-WindSpeed+v0.x)+sin(_-Time.x*_-WindSpeed+v0.z*2),0,cos(_-Time.x*_-WindSpeed+v0.x*2)+cos(_-Time.x*_-WindSpeed+v0.z))//Anzahl
//(_Time.x+v0.x+v0.z看起来“随机”,因为它使用时间+坐标)
v1+=风*风力强度;
v2+=(风力*_风力/2)/2;
float3 color=(在[0].color中);//GRA的颜色
浮动sin30=0.5;
浮动sin60=0.866f;
浮点数cos30=sin60;
浮点数cos60=sin30;
g2f输出;
//Quad1-下面的代码可以放在一个函数中(但是!)它在MacOSX上不起作用,这就是为什么它仍然要计算很长一段时间
OUT.pos=单位对象到LIPPOS(v0+垂直角*0.5*_高度);
OUT.norm=faceNormal;
OUT.diffuseColor=颜色;
OUT.uv=float2(1,0);
追加(输出);
OUT.pos=单位对象到LIPPOS(v1+垂直角*0.5*_高度);
OUT.norm=faceNormal;
OUT.diffuseColor=颜色;
OUT.uv=float2(1,1);
追加(输出);
OUT.pos=单位对象到lippos(v0);
OUT.norm=faceNormal;
OUT.diffuseColor=颜色;
OUT.uv=float2(0.5,0);
追加(输出);
OUT.pos=单位对象到lippos(v1);
OUT.norm=faceNormal;
OUT.diffuseColor=颜色;
OUT.uv=float2(0.5,1);
追加(输出);
OUT.pos=单位对象到LIPPOS(v1-垂直角*0.5*_高度);
OUT.norm=faceNormal;
OUT.diffuseColor=颜色;
OUT.uv=float2(0,1);
追加(输出);
OUT.pos=UnityObje
#include "AutoLight.cginc"
#pragma multi_compile_fwdbase
SHADOW_COORDS(3) // (3) means we are using TEXCOORD3
TRANSFER_SHADOW(OUT)
half shadow = SHADOW_ATTENUATION(IN)
Pass {
    Name "ShadowCaster"
    Tags { "LightMode" = "ShadowCaster" }

    ZWrite On ZTest LEqual

    CGPROGRAM
    #pragma target 2.0

    #pragma multi_compile_shadowcaster

    #pragma vertex vertShadowCaster
    #pragma fragment fragShadowCaster

    #include "UnityStandardShadow.cginc"

    ENDCG
}