gpt4 book ai didi

c++ - 用于立方体贴图表面上的光泽镜面反射的 GLSL 着色器

转载 作者:IT老高 更新时间:2023-10-28 22:20:43 26 4
gpt4 key购买 nike

我为环境立方体贴图写了一个着色器

*顶点着色器*

varying vec3 Normal;
varying vec3 EyeDir;
uniform samplerCube cubeMap;

void main()
{
gl_Position = gl_ModelViewProjectionMatrix*gl_Vertex;
Normal = gl_NormalMatrix * gl_Normal;
EyeDir = vec3(gl_ModelViewMatrix * gl_Vertex);
}

*片段着色器 *

varying vec3 Normal;
varying vec3 EyeDir;

uniform samplerCube cubeMap;

void main(void)
{
vec3 reflectedDirection = normalize(reflect(EyeDir, normalize(Normal)));
reflectedDirection.y = -reflectedDirection.y;
vec4 fragColor = textureCube(cubeMap, reflectedDirection);
gl_FragColor = fragColor;
}

这是经典的结果: http://braintrekking.files.wordpress.com/2012/07/glsl_cubemapreflection.png?w=604&h=466现在我想添加一些高光白色高光以获得更有光泽的效果,比如珍珠母。怎么可能添加这种亮点?就像这张图片中的一样,我应该将镜面反射分量与 gl_FragColor 相加吗?第一次尝试是在顶点着色器中计算镜面反射

vec3 s = normalize(vec3(gl_LightSource[0].position - EyeDir));
vec3 v = normalize(EyeDir);
vec3 r = reflect( s, Normal );
vec3 ambient = vec3(gl_LightSource[0].ambient*gl_FrontMaterial.ambient);

float sDotN = max( dot(s,Normal), 0.0 );
vec3 diffuse = vec3(gl_LightSource[0].diffuse * gl_FrontMaterial.diffuse * sDotN);
vec3 spec = vec3(0.0);
if( sDotN > 0.0 )
spec = gl_LightSource[0].specular * gl_FrontMaterial.specular * pow( max( dot(r,v), 2.0 ), gl_FrontMaterial.shininess );

LightIntensity = 0*ambient + 0*diffuse + spec;

并将其乘以 gl_FragColor 但我得到的效果并不令人信服。

有人知道怎么做吗?

最佳答案

以下是您如何做到这一点的示例:

珍珠母效果关闭:
enter image description here
珍珠母贝效果开启:
enter image description here

顶点着色器:

uniform vec3 fvEyePosition;

varying vec3 ViewDirection;
varying vec3 Normal;

void main( void )
{
gl_Position = ftransform();
vec4 fvObjectPosition = gl_ModelViewMatrix * gl_Vertex;

ViewDirection = fvEyePosition - fvObjectPosition.xyz;
Normal = gl_NormalMatrix * gl_Normal;
}

片段着色器:

uniform samplerCube cubeMap;

varying vec3 ViewDirection;
varying vec3 Normal;

const float mother_pearl_brightness = 1.5;

#define MOTHER_PEARL

void main( void )
{
vec3 fvNormal = normalize(Normal);
vec3 fvViewDirection = normalize(ViewDirection);
vec3 fvReflection = normalize(reflect(fvViewDirection, fvNormal));

#ifdef MOTHER_PEARL
float view_dot_normal = max(dot(fvNormal, fvViewDirection), 0.0);
float view_dot_normal_inverse = 1.0 - view_dot_normal;

gl_FragColor = textureCube(cubeMap, fvReflection) * view_dot_normal;
gl_FragColor.r += mother_pearl_brightness * textureCube(cubeMap, fvReflection + vec3(0.1, 0.0, 0.0) * view_dot_normal_inverse) * (1.0 - view_dot_normal);
gl_FragColor.g += mother_pearl_brightness * textureCube(cubeMap, fvReflection + vec3(0.0, 0.1, 0.0) * view_dot_normal_inverse) * (1.0 - view_dot_normal);
gl_FragColor.b += mother_pearl_brightness * textureCube(cubeMap, fvReflection + vec3(0.0, 0.0, 0.1) * view_dot_normal_inverse) * (1.0 - view_dot_normal);
#else
gl_FragColor = textureCube(cubeMap, fvReflection);
#endif
}

当然,计算 R、G 和 B 分量的方式不是很正确,但我发布此代码是为了向您展示方法,而不是解决方案。


编辑:

这是彩虹色着色器 promise 的“正确”版本:

顶点着色器:

varying vec3 v_view_direction;
varying vec3 v_normal;
varying vec2 v_texture_coordinate;

void main(void)
{
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
v_texture_coordinate = gl_MultiTexCoord0.xy;
v_view_direction = -gl_ModelViewMatrix[3].xyz;
v_normal = gl_NormalMatrix * gl_Normal;
}

片段着色器:

uniform samplerCube texture_reflection;
uniform sampler2D texture_iridescence;
uniform sampler2D texture_noise;

varying vec3 v_view_direction;
varying vec3 v_normal;
varying vec2 v_texture_coordinate;

const float noise_strength = 0.5;

void main(void)
{
vec3 n_normal = normalize(v_normal);
vec3 n_wiew_direction = normalize(v_view_direction);
vec3 n_reflection = normalize(reflect(n_wiew_direction, n_normal));

vec3 noise_vector = (texture2D(texture_noise, v_texture_coordinate).xyz - vec3(0.5)) * noise_strength;

float inverse_dot_view = 1.0 - max(dot(normalize(n_normal + noise_vector), n_wiew_direction), 0.0);
vec3 lookup_table_color = texture2D(texture_iridescence, vec2(inverse_dot_view, 0.0)).rgb;

gl_FragColor.rgb = textureCube(texture_reflection, n_reflection).rgb * lookup_table_color * 2.5;
gl_FragColor.a = 1.0;
}

结果

没有虹彩效果:
enter image description here

虹彩效果(查找纹理1):
enter image description here

虹彩效果(查找纹理2):
enter image description here

彩虹色查找纹理 2: enter image description here

噪点纹理:
enter image description here

备注:
彩虹色查找纹理也可以是 1D 纹理,这样会更节省内存。
另外,计算噪声 vector 的方式实际上是胡说八道。正确的解决方案是使用凹凸贴图。但是,嘿,它有效! :D

关于c++ - 用于立方体贴图表面上的光泽镜面反射的 GLSL 着色器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11794277/

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