逐像素、逐顶点光照差异对比

逐像素、逐顶点光照差异

逐像素、逐顶点光照差异性主要体现在对于非精细模型,在执行逐顶点光照时,由于点距较大,在进行颜色线性插值的过程中,无法精细平滑过渡,导致效果变差。

1、  逐像素(光照计算过程在片元着色器中完成)
顶点着色

varying vec4 diffuse,ambient;

varying vec3 normal,lightDir,viewDir;

void main()

{  

      normal = normalize(gl_NormalMatrix * gl_Normal);

     

      lightDir = normalize(vec3(gl_LightSource[0].position));

 

      //相机观察向量,顶点->人眼,用于计算镜面反射

      viewDir = normalize(gl_LightSource[0].halfVector.xyz);

 

      diffuse = gl_FrontMaterial.diffuse * gl_LightSource[0].diffuse;

      ambient = gl_FrontMaterial.ambient * gl_LightSource[0].ambient;

      ambient += gl_LightModel.ambient * gl_FrontMaterial.ambient;//全局环境光

       

      gl_Position = ftransform();

    }

片元着色

varying vec4 diffuse,ambient;

varying vec3 normal,lightDir, viewDir;

void main()

{

      vec3 n,viewVec;

      float dfse,spec;

     

      vec4 color = ambient;

     

      n = normalize(normal);

   

      dfse = max(dot(n,lightDir),0.0); //漫反射

     

     if (dfse > 0.0)   //没有漫反射,镜面反射也不存在

{

         color += diffuse * dfse;

         viewVec = normalize(viewDir);

         spec = max(dot(n, viewVec),0.0); //镜面反射

 

         color += gl_FrontMaterial.specular *

               gl_LightSource[0].specular *

               pow(spec, gl_FrontMaterial.shininess);

      }

      gl_FragColor = color;

   }

2、  逐顶点光照(光照计算过程在顶点着色器中完成)

顶点着色

varying vec4 color;

void main()

{  

vec4 diffuse,ambient;

vec3 normal,lightDir, viewDir;

 

     normal = normalize(gl_NormalMatrix * gl_Normal);

     

     lightDir = normalize(vec3(gl_LightSource[0].position));

 

      //相机观察向量,顶点->人眼,用于计算镜面反射

      viewDir = normalize(gl_LightSource[0].halfVector.xyz);

 

      diffuse = gl_FrontMaterial.diffuse * gl_LightSource[0].diffuse;

      ambient = gl_FrontMaterial.ambient * gl_LightSource[0].ambient;

      ambient += gl_LightModel.ambient * gl_FrontMaterial.ambient;//全局环境光

       

      float dfse,spec;    

      color = ambient;

      dfse = max(dot(normal,lightDir),0.0); //漫反射

     

     if (dfse > 0.0)   //没有漫反射,镜面反射也不存在

{

         color += diffuse * dfse;

         spec = max(dot(normal, viewDir),0.0); //镜面反射

 

         color += gl_FrontMaterial.specular *

               gl_LightSource[0].specular *

               pow(spec, gl_FrontMaterial.shininess);

      }

      gl_Position = ftransform();

   }

片元着色

varying vec4 color;

void main()

{     

      gl_FragColor = color;

   }

 

效果对比图(逐像素、逐顶点)

 

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要实现模型的光照像素着色,而不是按面着色,可以使用Three.js中的ShaderMaterial(着色器材质)。 ShaderMaterial允许您使用自定义GLSL着色器编写渲染程序,从而可以更精细地控制模型的渲染过程。通过使用自定义着色器,您可以控制每个像素光照计算,从而实现按像素着色。 以下是一个简单的示例: 首先,您需要编写自定义的顶点着色器和片段着色器。例如,以下代码片段演示了如何计算每个像素光照: ``` varying vec3 vNormal; // 传递法线向量到片段着色器中 varying vec3 vViewPosition; // 传递相机位置到片段着色器中 void main() { // 计算法线向量 vNormal = normalMatrix * normal; // 计算顶点在相机坐标系中的位置 vec4 viewPosition = modelViewMatrix * vec4(position, 1.0); vViewPosition = -viewPosition.xyz; // 输出变换后的顶点位置 gl_Position = projectionMatrix * viewPosition; } ``` ``` uniform vec3 uAmbientLightColor; // 环境光颜色 uniform vec3 uDirectionalLightColor; // 方向光颜色 uniform vec3 uDirectionalLightDirection; // 方向光方向 varying vec3 vNormal; // 从顶点着色器中传递的法线向量 varying vec3 vViewPosition; // 从顶点着色器中传递的相机位置 void main() { // 计算环境光照 vec3 ambient = uAmbientLightColor; // 计算方向光照 vec3 directional = vec3(0.0); vec3 lightDirection = normalize(uDirectionalLightDirection); float diffuse = max(dot(vNormal, lightDirection), 0.0); directional = uDirectionalLightColor * diffuse; // 计算最终颜色 vec3 color = ambient + directional; gl_FragColor = vec4(color, 1.0); } ``` 接下来,创建ShaderMaterial并将其分配给您的模型。例如,以下代码片段演示了如何创建一个着色器材质并将其应用于模型: ``` var material = new THREE.ShaderMaterial({ uniforms: { uAmbientLightColor: { value: new THREE.Color('#ffffff') }, uDirectionalLightColor: { value: new THREE.Color('#ffffff') }, uDirectionalLightDirection: { value: new THREE.Vector3() } }, vertexShader: document.getElementById('vertexShader').textContent, fragmentShader: document.getElementById('fragmentShader').textContent }); var mesh = new THREE.Mesh(geometry, material); scene.add(mesh); ``` 请注意,uniforms属性用于向着色器中传递变量,vertexShader属性包含顶点着色器代码,fragmentShader属性包含片段着色器代码。 最后,您需要设置每个像素光照计算所需的uniforms值。例如,以下代码片段演示了如何设置方向光照的方向: ``` material.uniforms.uDirectionalLightDirection.value = new THREE.Vector3(0, 0, 1); ``` 如果您需要更高级的光照计算,可以使用其他uniforms变量来传递其他参数,例如材质的反射率、镜面反射等。 希望这可以帮助您实现按像素着色的模型光照

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值