Games202作业0及优化部分

完成部分:

  • 环境和框架搭建
  • bllin-phong光照模型

优化部分:

  • 从文件加载shader

遇到的问题:

  • 模型偶尔加载不出来
  • shader参数设置不正确

环境和框架搭建

根据文档搭建好环境后,运行后会执行默认材质,效果如下:

由于默认材质直接使用贴图颜色,没有执行任何光照计算,所以模型不会随光源位置发生任何改变。在此过程中会遇到模型偶尔加载不出来的问题,参见bug部分。

Bllin-Phong光照模型

1.添加shader

该部分可以直接以字符串形式加入到InternalShader.js中,也可以从文件中加载,参加优化部分

2.修改index.html,在material.js后面添加phongmaterial.js

<script src="src/materials/PhongMaterial.js" defer></script>

3.将loadOBJ.js中的材质定义部分(第40~56行)换成phongmaterial

let myMaterial = new PhongMaterial(mat.color.toArray(), colorMap, mat.specular.toArray(), renderer.lights[0].entity.mat.intensity);

4.增加PhongMaterial

class PhongMaterial extends Material {
    /**
     * Creates an instance of PhongMaterial.
     * @param {vec3f} color The material color
     * @param {Texture} colorMap The texture object of the material
     * @param {vec3f} specular The material specular coefficient
     * @param {float} intensity The light intensity
     * @memberof PhongMaterial
     */
    constructor(color, colorMap, specular, intensity) {
        let textureSample = 0;
        if (colorMap != null) {
            textureSample = 1;
            super({
                'uTextureSample': { type:'1i', value:textureSample },
                'uSampler': { type: 'texture', value: colorMap },
                'uKd': { type:'3fv', value:color },
                'uKs': { type:'3fv', value:specular },
                'uLightIntensity': { type: '1f', value: intensity }
                }, [], PhongVertexShader, PhongFragmentShader);
        } else {
            // console.log(color);
            super({
                'uTextureSample': { type:'1i', value:textureSample },
                'uKd': { type:'3fv', value:color },
                'uKs': { type:'3fv', value:specular },
                'uLightIntensity': { type:'1f', value:intensity }
                }, [], PhongVertexShader, PhongFragmentShader);
        }
    }
}

最终可以达到的效果如下:

 

从文件加载Shader

因为Shader需要在渲染之前完成加载和绑定,并且PhongShader本身并不大,故而使用同步实现。首先,在loadShader.js中增加以下函数用于同步读取Shader文件:

function loadShaderFromFile(filePath) {
    var xhr = new XMLHttpRequest();
    xhr.open('GET', filePath, false); // 使用同步请求
    xhr.send(null);
  
    if (xhr.status === 200) {
        return xhr.responseText;
    } else {
        console.error('无法加载着色器文件:', filePath);
        return null;
    }
}

其次,在PhongMaterial的构造函数中增加以下四行代码用于从文件中读取Shader:

const phongVertexPath = 'src/shaders/phongShader/vertex.glsl';
const phongFragmentPath = 'src/shaders/phongShader/fragment.glsl';
var PhongVertexShader = loadShaderFromFile(phongVertexPath);
var PhongFragmentShader = loadShaderFromFile(phongFragmentPath);

如果不出问题,效果与采用静态字符串形式的无二。

一些bug

1.模型加载不出来

有两个可能的原因,可以通过刷新几次进行甄别。

如果偶尔能显示,应该是材质加载的问题,在loadOBJ.js中,有这样一个语句materials.preload();这个语句会进行资源的异步加载,但随便将该materials进行了传参,此时materials可能还没加载完成,导致在渲染模型的时候无法正确应用材质。解决方法是在Index.html中加入以下代码声明材质的预加载:

<link rel="preload" href="/assets/mary/MC003_Kozakura_Mari.png" as="image" type="image/png" crossorigin/>

还有可能是shader不对,Material.js中可以发现如下语句:

this.#flatten_uniforms = ['uModelViewMatrix', 'uProjectionMatrix', 'uCameraPos', 'uLightPos'];

在给shader传参时,使用的是modelview矩阵,也就是把模型矩阵和视图矩阵的乘积传入,shader里也应该是如此。

2.shader参数设置不正确

在完成所有工作后,发现渲染出来的模型是灰色,这个问题很脑残,原因是在复制pdf中的PhongMaterial.js多一些空格,,,导致参数映射不正确。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值