15.透明shader

首先透明的shader应该是最后渲染的,如果一开始就渲染有可能被场景中不透明的挡住。

shader:

// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
Shader "Custom/NormalMapShader-Frag"
{
    Properties
    {
        _Color("Color",Color) = (1,1,1,1)
        _MainTex("Main Tex",2D) = "white"{}
        //_Gloss("Gloss",Range(8,200)) = 10
        _Specular("Specular",Color) = (1,1,1,1)
        _NormalMap("NormalMap",2D) = "bump"{}   //bump 代表使用自身的法线
        _BumpScale("BumpScale",Float) = 1  //法线高度力度
        _AlphaScale("AlphaScale",Float) = 1 //透明度
    }
    SubShader
    {
        Tags{"Queue" = "Transparent" "IngnoreProjector" = "True" "RenderType" = "Transparent" }  //
        pass
        {
            Tags { "LightMode"="ForwardBase" }
            ZWrite Off  //深度写入关闭
            Blend SrcAlpha OneMinusSrcAlpha
            CGPROGRAM
            #include "Lighting.cginc"
            #pragma vertex vert
            #pragma fragment frag
            fixed4 _Color;
            sampler2D _MainTex;
            sampler2D _NormalMap;
            half _Gloss;
            fixed3 _Specular;
            float4 _MainTex_ST;
            float4 _NormalMap_ST;
            float _BumpScale;
            float _AlphaScale;
            struct a2v
            {
                float4 vertex:POSITION;
                //切线空间的确定是通过法线和切线来确定的
                float3 normal:NORMAL;
                float4 tangent:TANGENT;//tanget.w是用来确定切线空间坐标轴的方向的
                float2 texcoord:TEXCOORD;
            };
            struct v2f
            {
                float4 pos:SV_POSITION;
                fixed3 worldNormalDir:color;
                float4 worldVert:TEXCOORD1;
                float4 uv:TEXCOORD2;     //xy 用来存储MainTex的纹理坐标  zw用来存储NormalMap的纹理坐标
                float3 tangentSpaceLightDir:TEXCOORD0;  //切线空间下光的方向
            };
            v2f vert(a2v v) //这里参数的名字必须是v 因为在这个宏TANGENT_SPACE_ROTATION里会调用v里的法线和切线
            {
                v2f f;
                f.pos = UnityObjectToClipPos(v.vertex);//UnityObjectToClipPos(i.vertex);
                //o.worldNormalDir = mul(i.normal,(float3x3)unity_WorldToObject);
                //o.worldNormalDir = UnityObjectToWorldNormal(i.normal);
                f.worldVert = mul(unity_ObjectToWorld, v.vertex);
                f.uv.xy = v.texcoord * _MainTex_ST.xy + _MainTex_ST.zw;
                f.uv.zw = v.texcoord * _NormalMap_ST.xy + _NormalMap_ST.zw;
                TANGENT_SPACE_ROTATION;//调用这个宏后会得到一个矩阵rotation 用来把模型空间下的方向转成切线空间下
                f.tangentSpaceLightDir = mul(rotation, ObjSpaceLightDir(v.vertex));
                return f;
            }
            //把所有跟法线方向有关的运算全都放在切线空间下
            float4 frag(v2f f):SV_TARGET
            {
                //fixed3 worldNormalDir = mul(i.normal,(float3x3)unity_WorldToObject);
                
                //使用法线贴图后不需要直接取模型的了
                //fixed3 normalDir = normalize(i.worldNormalDir);  //这个矩阵把一个方向从世界空间转换到模型空间  这样放在后面就是模型到世界了
                fixed4 normalColor = tex2D(_NormalMap,f.uv.zw);
                //(贴图类型被unity识别成NormalType后会被unity进行处理使用自己的方法会读取的不正确使用unity提供的UnpackNormal)
                fixed3 tangentSpaceNormalDir = UnpackNormal(normalColor);
                tangentSpaceNormalDir.xy = tangentSpaceNormalDir.xy * _BumpScale;   //模型原法线和法线贴图的轴应该是一样的不需要改变
                tangentSpaceNormalDir = normalize(tangentSpaceNormalDir);//normalize(normalColor.xyz * 2 - 1);//切线空间下的法线的方向
                //fixed3 lightDir = normalize(_WorldSpaceLightPos0.xyz);//对于每个顶点来说光的位置就是光的方向,因为光是平行的。
                fixed3 lightDir = normalize(f.tangentSpaceLightDir);
                fixed3 halfLambert = dot(tangentSpaceNormalDir,lightDir) * 0.5 + 0.5;  //半兰伯特光照公式 max(dot(normalDir,lightDir),0);
                fixed3 texColor = tex2D(_MainTex,f.uv) * _Color;
                fixed3 diffuse = _LightColor0.rgb * halfLambert * texColor;//取得漫反射的颜色
                fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.rgb * texColor;//获取环境光
                
                //fixed3 reflectDir = normalize(reflect(-lightDir,normalDir));//反射光方向 
                //fixed3 viewDir = normalize(_WorldSpaceCameraPos.xyz - i.pos.xyz);//视野方向
                fixed3 viewDir = normalize(UnityWorldSpaceViewDir(f.worldVert.xyz));
                fixed3 halfDir = normalize(viewDir + lightDir);
                //fixed3 specular = _LightColor0.rgb * _Specular * pow(max(dot(tangentSpaceNormalDir, halfDir) , 0) , _Gloss);
                fixed3 tempColor = diffuse + ambient;
                return fixed4(tempColor,_AlphaScale);
            }  
            ENDCG
        }
    }
    //FallBack "Diffuse"
}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在Three.js中使用透明视频着色器,您需要先将视频纹理加载到Three.js中。这可以通过以下代码完成: ``` var video = document.createElement( 'video' ); video.src = 'path/to/video.mp4'; var texture = new THREE.VideoTexture( video ); texture.minFilter = THREE.LinearFilter; texture.magFilter = THREE.LinearFilter; texture.format = THREE.RGBFormat; ``` 接下来,您需要创建一个着色器材质并将视频纹理传递给它: ``` var material = new THREE.ShaderMaterial({ uniforms: { videoTexture: { value: texture }, opacity: { value: 1.0 } }, vertexShader: document.getElementById( 'vertexShader' ).textContent, fragmentShader: document.getElementById( 'fragmentShader' ).textContent, transparent: true }); ``` 在这个着色器材质中,我们有一个`uniforms`对象,其中包含我们的视频纹理和不透明度值。我们还设置了`transparent`属性为`true`,这是因为我们想要材质透明的。 接下来,我们需要编写我们的片段着色器代码。这将允许我们在视频上应用透明度。以下是一个简单的透明视频着色器片段着色器代码: ``` uniform sampler2D videoTexture; uniform float opacity; varying vec2 vUv; void main() { vec4 texel = texture2D( videoTexture, vUv ); gl_FragColor = vec4( texel.rgb, opacity * texel.a ); } ``` 在这个着色器中,我们定义了一个`uniform`变量`opacity`,这是我们将要传递给着色器的不透明度值。我们将纹理的alpha值乘以不透明度值,以实现透明度效果。 最后,将材质应用于您的对象: ``` var geometry = new THREE.PlaneGeometry( 10, 10 ); var mesh = new THREE.Mesh( geometry, material ); scene.add( mesh ); ``` 这将创建一个平面几何体,并将透明视频材质应用于它。现在,您将能够在Three.js场景中看到您的透明视频。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值