gpt4 book ai didi

unity3d - 统一 - 有光泽的模糊 Material ?

转载 作者:行者123 更新时间:2023-12-02 04:26:53 25 4
gpt4 key购买 nike

好的,我正在尝试制作像这样的标准模糊 Material (变暗的节拍军刀菜单)

enter image description here

enter image description here

但在 3D 对象上,不是相机效果或 Canvas Material 。我找到了一些提供低质量模糊的 Assets ,但我需要它有光泽,并且需要漂亮的高斯模糊。我的那个有奇怪的条纹:

enter image description here

//升级注意:将“mul(UNITY_MATRIX_MVP,)”替换为“UnityObjectToClipPos()”

Shader "Custom/WaterBlur" {
Properties {
_blurSizeXY("BlurSizeXY", Range(0,10)) = 0
}
SubShader {

// Draw ourselves after all opaque geometry
Tags { "Queue" = "Transparent" }

// Grab the screen behind the object into _GrabTexture
GrabPass { }

// Render the object with the texture generated above
Pass {


CGPROGRAM
#pragma debug
#pragma vertex vert
#pragma fragment frag
#ifndef SHADER_API_D3D11

#pragma target 3.0

#else

#pragma target 4.0

#endif

sampler2D _GrabTexture : register(s0);
float _blurSizeXY;

struct data {

float4 vertex : POSITION;

float3 normal : NORMAL;

};



struct v2f {

float4 position : POSITION;

float4 screenPos : TEXCOORD0;

};



v2f vert(data i){

v2f o;

o.position = UnityObjectToClipPos(i.vertex);

o.screenPos = o.position;

return o;

}



half4 frag( v2f i ) : COLOR

{

float2 screenPos = i.screenPos.xy / i.screenPos.w;
float depth= _blurSizeXY*0.0005;

screenPos.x = (screenPos.x + 1) * 0.5;

screenPos.y = 1-(screenPos.y + 1) * 0.5;

half4 sum = half4(0.0h,0.0h,0.0h,0.0h);
sum += tex2D( _GrabTexture, float2(screenPos.x-5.0 * depth, screenPos.y+5.0 * depth)) * 0.025;
sum += tex2D( _GrabTexture, float2(screenPos.x+5.0 * depth, screenPos.y-5.0 * depth)) * 0.025;

sum += tex2D( _GrabTexture, float2(screenPos.x-4.0 * depth, screenPos.y+4.0 * depth)) * 0.05;
sum += tex2D( _GrabTexture, float2(screenPos.x+4.0 * depth, screenPos.y-4.0 * depth)) * 0.05;


sum += tex2D( _GrabTexture, float2(screenPos.x-3.0 * depth, screenPos.y+3.0 * depth)) * 0.09;
sum += tex2D( _GrabTexture, float2(screenPos.x+3.0 * depth, screenPos.y-3.0 * depth)) * 0.09;

sum += tex2D( _GrabTexture, float2(screenPos.x-2.0 * depth, screenPos.y+2.0 * depth)) * 0.12;
sum += tex2D( _GrabTexture, float2(screenPos.x+2.0 * depth, screenPos.y-2.0 * depth)) * 0.12;

sum += tex2D( _GrabTexture, float2(screenPos.x-1.0 * depth, screenPos.y+1.0 * depth)) * 0.15;
sum += tex2D( _GrabTexture, float2(screenPos.x+1.0 * depth, screenPos.y-1.0 * depth)) * 0.15;



sum += tex2D( _GrabTexture, screenPos-5.0 * depth) * 0.025;
sum += tex2D( _GrabTexture, screenPos-4.0 * depth) * 0.05;
sum += tex2D( _GrabTexture, screenPos-3.0 * depth) * 0.09;
sum += tex2D( _GrabTexture, screenPos-2.0 * depth) * 0.12;
sum += tex2D( _GrabTexture, screenPos-1.0 * depth) * 0.15;
sum += tex2D( _GrabTexture, screenPos) * 0.16;
sum += tex2D( _GrabTexture, screenPos+5.0 * depth) * 0.15;
sum += tex2D( _GrabTexture, screenPos+4.0 * depth) * 0.12;
sum += tex2D( _GrabTexture, screenPos+3.0 * depth) * 0.09;
sum += tex2D( _GrabTexture, screenPos+2.0 * depth) * 0.05;
sum += tex2D( _GrabTexture, screenPos+1.0 * depth) * 0.025;

return sum/2;

}
ENDCG
}
}

Fallback Off
}

我怎样才能为网格完成一个有光泽的,甚至只是一个高质量的高斯模糊 Material ?

最佳答案

如果你想在你的表面上添加光泽,这是一种基于 Glossy Textures 中的着色器的方法。 Unity Community wiki 中的文章复制如下:

Shader "Cg per-pixel lighting with texture" {
Properties {
_MainTex ("RGBA Texture For Material Color", 2D) = "white" {}
_Color ("Diffuse Material Color", Color) = (1,1,1,1)
_SpecColor ("Specular Material Color", Color) = (1,1,1,1)
_Shininess ("Shininess", Float) = 10
}
SubShader {
Pass {
Tags { "LightMode" = "ForwardBase" }
// pass for ambient light and first light source

CGPROGRAM

#pragma vertex vert
#pragma fragment frag

#include "UnityCG.cginc"
uniform float4 _LightColor0;
// color of light source (from "Lighting.cginc")

// User-specified properties
uniform sampler2D _MainTex;
uniform float4 _Color;
uniform float4 _SpecColor;
uniform float _Shininess;

struct vertexInput {
float4 vertex : POSITION;
float3 normal : NORMAL;
float4 texcoord : TEXCOORD0;
};
struct vertexOutput {
float4 pos : SV_POSITION;
float4 posWorld : TEXCOORD0;
float3 normalDir : TEXCOORD1;
float4 tex : TEXCOORD2;
};

vertexOutput vert(vertexInput input)
{
vertexOutput output;

float4x4 modelMatrix = unity_ObjectToWorld;
float4x4 modelMatrixInverse = unity_WorldToObject;

output.posWorld = mul(modelMatrix, input.vertex);
output.normalDir = normalize(
mul(float4(input.normal, 0.0), modelMatrixInverse).xyz);
output.tex = input.texcoord;
output.pos = mul(UNITY_MATRIX_MVP, input.vertex);
return output;
}

float4 frag(vertexOutput input) : COLOR
{
float3 normalDirection = normalize(input.normalDir);

float3 viewDirection = normalize(
_WorldSpaceCameraPos - input.posWorld.xyz);
float3 lightDirection;
float attenuation;

float4 textureColor = tex2D(_MainTex, input.tex.xy);

if (0.0 == _WorldSpaceLightPos0.w) // directional light?
{
attenuation = 1.0; // no attenuation
lightDirection =
normalize(_WorldSpaceLightPos0.xyz);
}
else // point or spot light
{
float3 vertexToLightSource =
_WorldSpaceLightPos0.xyz - input.posWorld.xyz;
float distance = length(vertexToLightSource);
attenuation = 1.0 / distance; // linear attenuation
lightDirection = normalize(vertexToLightSource);
}

float3 ambientLighting = textureColor.rgb
* UNITY_LIGHTMODEL_AMBIENT.rgb * _Color.rgb;

float3 diffuseReflection = textureColor.rgb
* attenuation * _LightColor0.rgb * _Color.rgb
* max(0.0, dot(normalDirection, lightDirection));

float3 specularReflection;
if (dot(normalDirection, lightDirection) < 0.0)
// light source on the wrong side?
{
specularReflection = float3(0.0, 0.0, 0.0);
// no specular reflection
}
else // light source on the right side
{
specularReflection = attenuation * _LightColor0.rgb
* _SpecColor.rgb * (1.0 - textureColor.a)
// for usual gloss maps: "... * textureColor.a"
* pow(max(0.0, dot(
reflect(-lightDirection, normalDirection),
viewDirection)), _Shininess);
}

return float4(ambientLighting + diffuseReflection
+ specularReflection, 1.0);
}

ENDCG
}

Pass {
Tags { "LightMode" = "ForwardAdd" }
// pass for additional light sources
Blend One One // additive blending

CGPROGRAM

#pragma vertex vert
#pragma fragment frag

#include "UnityCG.cginc"
uniform float4 _LightColor0;
// color of light source (from "Lighting.cginc")

// User-specified properties
uniform sampler2D _MainTex;
uniform float4 _Color;
uniform float4 _SpecColor;
uniform float _Shininess;

struct vertexInput {
float4 vertex : POSITION;
float3 normal : NORMAL;
float4 texcoord : TEXCOORD0;
};
struct vertexOutput {
float4 pos : SV_POSITION;
float4 posWorld : TEXCOORD0;
float3 normalDir : TEXCOORD1;
float4 tex : TEXCOORD2;
};

vertexOutput vert(vertexInput input)
{
vertexOutput output;

float4x4 modelMatrix = unity_ObjectToWorld;
float4x4 modelMatrixInverse = unity_WorldToObject;

output.posWorld = mul(modelMatrix, input.vertex);
output.normalDir = normalize(
mul(float4(input.normal, 0.0), modelMatrixInverse).xyz);
output.tex = input.texcoord;
output.pos = mul(UNITY_MATRIX_MVP, input.vertex);
return output;
}

float4 frag(vertexOutput input) : COLOR
{
float3 normalDirection = normalize(input.normalDir);

float3 viewDirection = normalize(
_WorldSpaceCameraPos - input.posWorld.xyz);
float3 lightDirection;
float attenuation;

float4 textureColor = tex2D(_MainTex, input.tex.xy);

if (0.0 == _WorldSpaceLightPos0.w) // directional light?
{
attenuation = 1.0; // no attenuation
lightDirection =
normalize(_WorldSpaceLightPos0.xyz);
}
else // point or spot light
{
float3 vertexToLightSource =
_WorldSpaceLightPos0.xyz - input.posWorld.xyz;
float distance = length(vertexToLightSource);
attenuation = 1.0 / distance; // linear attenuation
lightDirection = normalize(vertexToLightSource);
}

float3 diffuseReflection = textureColor.rgb
* attenuation * _LightColor0.rgb * _Color.rgb
* max(0.0, dot(normalDirection, lightDirection));

float3 specularReflection;
if (dot(normalDirection, lightDirection) < 0.0)
// light source on the wrong side?
{
specularReflection = float3(0.0, 0.0, 0.0);
// no specular reflection
}
else // light source on the right side
{
specularReflection = attenuation * _LightColor0.rgb
* _SpecColor.rgb * (1.0 - textureColor.a)
// for usual gloss maps: "... * textureColor.a"
* pow(max(0.0, dot(
reflect(-lightDirection, normalDirection),
viewDirection)), _Shininess);
}

return float4(diffuseReflection
+ specularReflection, 1.0);
// no ambient lighting in this pass
}

ENDCG
}
}
Fallback "Specular"
}

您的模糊着色器的最终 Pass 需要合并到上述着色器中的第一个和第二个 Pass

着色器属性

如果这些属性尚不存在,请在模糊着色器中添加它们(如果存在,您可能需要重命名):

  _MainTex ("RGBA Texture For Material Color", 2D) = "white" {} 
_Color ("Diffuse Material Color", Color) = (1,1,1,1)
_SpecColor ("Specular Material Color", Color) = (1,1,1,1)
_Shininess ("Shininess", Float) = 10

第一个光泽 channel

设置标签以匹配光泽着色器:"LightMode"= "ForwardBase"

如果这些变量尚不存在,请将它们添加到传递中(如果它们存在,您可能需要重命名):

 uniform sampler2D _MainTex; 
uniform float4 _Color;
uniform float4 _SpecColor;
uniform float _Shininess;

在您的顶点输入结构中包含 float3 normal : NORMAL;

在顶点输出结构中包含 float4 posWorld : TEXCOORD0;float3 normalDir : TEXCOORD1;

vert函数中,设置output.posWorldoutput.normalDir,方法与glossy shader vert相同> 确实如此。

然后,在 frag 函数中,获取模糊着色器已经返回的内容,而不是返回它,而是将其用作第一个 中的 textureColor 变量>frag 函数在光泽着色器中,然后执行第一个光泽 frag 的其余部分。

您可能需要重命名代码中的其他内容,以使其适用于您已有的通行证。我不知道你的模糊着色器是什么样的,所以我不可能列出将两个 channel 合并在一起的每一步。

第二次光泽度

重复与第一个 gloss Pass 相同的过程,但使用第二个 gloss Pass 中的代码(特别重要的是不同的标签 "LightMode"= “转发添加”)

关于unity3d - 统一 - 有光泽的模糊 Material ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53712577/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com