IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> ogre-next吃鸡笔记 -> 正文阅读

[游戏开发]ogre-next吃鸡笔记

本人使用的版本是ogre-next2.3

一、OgreSTBICodec.cpp 中decode()函数??解码24位图片有bug,会导致jpg或者24位png无法显示

修复如下:

  Codec::DecodeResult STBIImageCodec::decode(DataStreamPtr& input) const
    {
        // Buffer stream into memory (TODO: override IO functions instead?)
        MemoryDataStream memStream(input, true);

        int width, height, components;
        stbi_uc *pixelData = stbi_load_from_memory(
            memStream.getPtr(), static_cast<int>( memStream.size() ), &width, &height, &components, 0 );

        if (!pixelData)
        {
            OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, 
                "Error decoding image: " + String(stbi_failure_reason()),
                "STBIImageCodec::decode");
        }

        ImageData2* imgData = OGRE_NEW ImageData2();

        imgData->box.depth = 1u; // only 2D formats handled by this codec
        imgData->box.numSlices = 1u;
        imgData->box.width = static_cast<uint32>( width );
        imgData->box.height = static_cast<uint32>( height );
        imgData->numMipmaps = 1u; // no mipmaps in non-DDS
        imgData->textureType = TextureTypes::Type2D;

        switch( components )
        {
            case 1:
                imgData->format = PFG_R8_UNORM;
                break;
            case 2:
                imgData->format = PFG_RG8_UNORM;
                break;
            case 3:
                imgData->format = PFG_RGBA8_UNORM;
                break;
            case 4:
                imgData->format = PFG_RGBA8_UNORM;
                break;
            default:
                stbi_image_free(pixelData);
                OGRE_DELETE imgData;
                OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND,
                            "Unknown or unsupported image format",
                            "STBIImageCodec::decode");
                break;
        }

        const uint32 rowAlignment = 4u;
        imgData->box.bytesPerPixel = PixelFormatGpuUtils::getBytesPerPixel( imgData->format );
        imgData->box.bytesPerRow = PixelFormatGpuUtils::getSizeBytes( imgData->box.width,
                                                                      1u, 1u, 1u,
                                                                      imgData->format,
                                                                      rowAlignment );
        imgData->box.bytesPerImage = imgData->box.bytesPerRow * imgData->box.height;

        imgData->box.data = OGRE_MALLOC_SIMD( imgData->box.bytesPerImage, MEMCATEGORY_RESOURCE );

        if( components != 3 )
            memcpy( imgData->box.data, pixelData, imgData->box.bytesPerImage );
        else
        {
            size_t realBytesPerRow = PixelFormatGpuUtils::getSizeBytes( imgData->box.width, 1u, 1u, 1u,
                                                                        PFG_RGB8_UNORM, rowAlignment );
            for( size_t y = 0; y < (size_t)height; ++y )
            {
                uint8 *pDst = reinterpret_cast<uint8 *>( imgData->box.at( 0u, y, 0u ) );
                uint8 const *pSrc = pixelData + y * realBytesPerRow;
                for( size_t x = 0; x < (size_t)width; ++x )
                {
                    const uint8 b = *pSrc++;
                    const uint8 g = *pSrc++;
                    const uint8 r = *pSrc++;

                    *pDst++ = b;
                    *pDst++ = g;
                    *pDst++ = r;
                    *pDst++ = 0xFF;
                }
            }
        }
        stbi_image_free(pixelData);

        DecodeResult ret;
        ret.first.reset();
        ret.second = CodecDataPtr(imgData);
        return ret;
    }

二、PBR材质使用

? ??一个简单的材质如下

hlms FireHydrant_01_Green_FireHydrant_01_Green pbs
{
?? ?roughness?? ?0.38
?? ?fresnel?? ??? ?1.33
?? ?specular?? ?1.0 1.0 1.0
?? ?
?? ?diffuse?? ??? ?3.14 3.14 3.14
?? ?emissive 0.05 0.05 0.05
?? ?workflow metallic_workflow
?? ?diffuse_map?? ??? ?FireHydrant_01_Green_C.png
?? ?normal_map?? ??? ?FireHydrant_01_N.png
?? ?//roughness_map?? ?FireHydrant_01_R.png
?? ?specular_map?? ?FireHydrant_01_M.png

}

注意Ogre支持三种PBR的工作流定义在OgreHlmsPbsDatablock.h文件中。默认的工作流是

SpecularWorkflow这个和国内常用的MetallicWorkflow不一致。

 enum Workflows
        {
            /// Specular workflow. Many popular PBRs use SpecularAsFresnelWorkflow
            /// though. @see setWorkflow
            SpecularWorkflow,

            /// Specular workflow where the specular texture is addressed to the fresnel
            /// instead of kS. This is normally referred as simply Specular workflow
            /// in many other PBRs. @see setWorkflow
            SpecularAsFresnelWorkflow,

             Metallic workflow. @see setWorkflow
            MetallicWorkflow,
        };

修改了OgreHlmsPbsDatablock.cpp文件中HlmsPbsDatablock的构造函数,增加Pbr材质中

workflow 关键字的支持,以通过材质指定工作流。增加代码如下:

 if( Hlms::findParamInVec( params, "uv_detail_weight_map", paramVal ) )
        {
            setTextureUvSource( PBSM_DETAIL_WEIGHT,
                                StringConverter::parseUnsignedInt( paramVal ) );
        }

        if( Hlms::findParamInVec( params, "workflow", paramVal ) )
        {
            if(paramVal.compare("metallic_workflow") == 0 )
            {
                setWorkflow( MetallicWorkflow );
            }
            else if (paramVal.compare("fresnel_workflow") == 0 )
            {
                setWorkflow( SpecularAsFresnelWorkflow );
            }
            else
            {
                setWorkflow( SpecularWorkflow );
            }  
        }

另外如果我们想知道pbr材质中支持哪些参数也可以查看该函数。比如:

? “background_diffuse”? “diffuse” “specular” “diffuse_map” 等等

??????

三、调试Pbs生成的shader. HLMS材质系统通过各种预定义的语法片段来生成最终shader.

例如在prb材质中设置好

????????specular_map????FireHydrant_01_M.png

则会用到? ? “Hlms/Pbs/Any/Main/800.PixelShader_piece_ps.any” 这个文件中的片段来生成对specular_map? ? 采样的shader。我们可以通过修改这个文件来调试这部分代码例如修改该文件

如下。增加一个中间变量 fff 合 ddd 可以看到在最中的shader中会存在该部分。在debug模式下

ogrenext会默认将shader保存成文件。ogre保存该调试shader代码的函数在 OgreHlms.cpp文件中的?void Hlms::compileShaderCode( ShaderCodeCache &codeCache )函数中的

?????????if( mDebugOutput )
? ? ? ? ? ? ? ? ? ? debugDumpFile.write( &outString[0], outString.size() );

????????

@piece( SampleSpecularMap )
	/// SPECUlAR MAP
	pixelData.specular.xyz = material.kS.xyz;
	@property( !metallic_workflow )
		pixelData.F0 = material.F0.@insertpiece( FresnelSwizzle );
		@property( specular_map && !fresnel_workflow )
		float3 fff =  SampleSpecular( textureMaps@value( specular_map_idx ),
													  samplerState@value(specular_map_sampler),
													  UV_SPECULAR( inPs.uv@value(uv_specular).xy ),
													  texIndex_specularIdx ).xyz;
			fff.g = fff.r;
			fff.b = fff.r;
			pixelData.specular.xyz *= fff;
		@end
		@property( specular_map && fresnel_workflow )
			pixelData.F0 *= SampleSpecular( textureMaps@value( specular_map_idx ),
											samplerState@value(specular_map_sampler),
											UV_SPECULAR( inPs.uv@value(uv_specular).xy ),
											texIndex_specularIdx ).@insertpiece( FresnelSwizzle );
		@end
	@else
		float metalness = material.F0.x;
		@property( specular_map )

		float3 ddd =  SampleSpecular( textureMaps@value( specular_map_idx ),
													  samplerState@value(specular_map_sampler),
													  UV_SPECULAR( inPs.uv@value(uv_specular).xy ),
													  texIndex_specularIdx ).xyz;
			ddd.g = ddd.r;
			ddd.b = ddd.r;
			pixelData.specular.xyz *= ddd;

		@end
		pixelData.F0 = lerp( make_float_fresnel( 0.03f ), pixelData.diffuse.xyz * 3.14159f, metalness );
		pixelData.diffuse.xyz = pixelData.diffuse.xyz - pixelData.diffuse.xyz * metalness;
		@property( hlms_alphablend || hlms_screen_space_refractions )
			pixelData.F0 *= material.F0.w; ///Should this be done for non-metallic as well???
		@end
	@end
	@property( transparent_mode || hlms_screen_space_refractions )
		pixelData.F0 *= pixelData.diffuse.w;
	@end
@end

4、 pbr材质中的漫反射贴图不可以全黑或者过黑,也就是像素的亮度接近于0,在shader中我们可以看到, 基本所有漫反射(环境光、漫反射光)相关的材质都会乘以漫反射贴图的颜色,所以如果贴图颜色过暗则直接导致物体显示偏暗,另外漫反射贴图也不可出现高对比度。否则亮的部分在强光下容易过度曝光导致发白。所以漫反射贴图一定要亮度适中,避免高对比度。

上左图中暗部无法被任何光源照亮,右图为ps增加亮度后的结果

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2022-02-19 01:31:05  更:2022-02-19 01:33:21 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/27 17:55:05-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码