Android OpenGL ES 开发教程(26):设置光照效果Set Lighting

本文深入探讨OpenGL中光照模型的使用,并结合OpenGLES API详细说明如何实现光照效果。内容涵盖设置光源、定义法线、设置物体材料光学属性,以及光源类型(平行光源、点光源、聚光灯)的配置方法。此外,文章还解释了如何为图形设置法线以产生光照效果,并提供规范化法向量和调整法线设置的技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

上一篇简单介绍了OpenGL中使用的光照模型,本篇结合OpenGL ES API说明如何使用光照效果:

  • 设置光源
  • 定义法线
  • 设置物体材料光学属性

光源

OpenGL ES中可以最多同时使用八个光源,分别使用0到7表示。

OpenGL ES光源可以分为

  • 平行光源(Parallel light source), 代表由位于无限远处均匀发光体,太阳可以近似控制平行光源。
  • 点光源(Spot light source) 如灯泡就是一个点光源,发出的光可以指向360度,可以为点光源设置光衰减属性(attenuation)或者让点光源只能射向某个方向(如射灯)。
  • 可以为图形的不同部分设置不同的光源。

下面方法可以打开某个光源,使用光源首先要开光源的总开关:

gl.glEnable(GL10.GL_LIGHTING);


然后可以再打开某个光源如0号光源:

gl.glEnable(GL10.GL_LIGHTI0);


设置光源方法如下:

  • public void glLightfv(int light,int pname, FloatBuffer params)
  • public void glLightfv(int light,int pname,float[] params,int offset)
  • public void glLightf(int light,int pname,float param)
  • light 指光源的序号,OpenGL ES可以设置从0到7共八个光源。
  • pname: 光源参数名称,可以有如下:GL_SPOT_EXPONENT, GL_SPOT_CUTOFF, GL_CONSTANT_ATTENUATION, GL_LINEAR_ATTENUATION, GL_QUADRATIC_ATTENUATION, GL_AMBIENT, GL_DIFFUSE,GL_SPECULAR, GL_SPOT_DIRECTION, GL_POSITION
  • params 参数的值(数组或是Buffer类型)。

其中为光源设置颜色的参数类型为GL_AMBIENT,GL_DIFFUSE,GL_SPECULAR,可以分别指定R,G,B,A 的值。

指定光源的位置的参数为GL_POSITION,值为(x,y,z,w):

平行光将w 设为0.0,(x,y,z)为平行光的方向:

对于点光源,将 w 设成非0值,通常设为1.0. (x,y,z)为点光源的坐标位置。

将点光源设置成聚光灯,需要同时设置GL_SPOT_DIRECTION,GL_SPOT_CUTOFF等 参数,GL_POSITION的设置和点光源类似:将 w 设成非0值,通常设为1.0. (x,y,z)为点光源的坐标位置。而对于GL_SPOT_DIRECTION 参数,设置聚光的方向(x,y,z)

GL_SPOT_CUTOFF 参数设置聚光等发散角度(0到90度)

GL_SPOT_EXPONENT 给出了聚光灯光源汇聚光的程度,值越大,则聚光区域越小(聚光能力更强)。

对应点光源(包括聚光灯),其它几个参数GL_CONSTANT_ATTENUATION, GL_LINEAR_ATTENUATION, GL_QUADRATIC_ATTENUATION 为点光源设置光线衰减参数,公式有如下形式,一般无需详细了解:

在场景中设置好光源后,下一步要为所绘制的图形设置法线(Normal),只有设置了法线,光源才能在所会物体上出现光照效果。三维平面的法线是垂直于该平面的三维向量。曲面在某点P处的法线为垂直于该点切平面的向量

和设置颜色类似,有两个方法可以为平面设置法线,一是

public void glNormal3f(float nx,float ny,float nz)

这个方法为后续所有平面设置同样的方向,直到重新设置新的法线为止。

为某个顶点设置法线:

public void glNormalPointer(int type,int stride, Buffer pointer)

  • type 为Buffer 的类型,可以为GL_BYTE, GL_SHORT, GL_FIXED,或 GL_FLOAT
  • stride: 每个参数之间的间隔,通常为0.
  • pointer: 法线值。

打开法线数组

gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);

用法和Color, Vertex 类似。参见Android OpenGL ES 开发教程(8):基本几何图形定义

规范化法向量,比如使用坐标变换(缩放),如果三个方向缩放比例不同的话,顶点或是平面的法线可能就有变好,此时需要打开规范化法线设置:

gl.glEnable(GL10.GL_NORMALIZE);


经过规范化后法向量为单位向量(长度为1)。同时可以打开缩放法线设置


gl.glEnable(GL10.GL_RESCALE_NORMAL);


设置好法线后,需要设置物体表面材料(Material)的反光属性(颜色和材质)。

将在下篇介绍设置物体表面材料(Material)的反光属性(颜色和材质)并给出一个光照的示例。

UATHelper: 打包 (Android (ASTC)): LogCook: Display: Cooked packages 3051 Packages Remain 592 Total 3643 UATHelper: 打包 (Android (ASTC)): LogOutputDevice: Warning: UATHelper: 打包 (Android (ASTC)): Script Stack (0 frames) : UATHelper: 打包 (Android (ASTC)): LogWindows: Error: appError called: Fatal error: [File:D:\build\++UE5\Sync\Engine\Source\Runtime\Engine\Private\ShaderCompiler\ShaderCompiler.cpp] [Line: 4668] UATHelper: 打包 (Android (ASTC)): /Engine/Private/LocalVertexFactoryCommon.ush:146:32: warning: conversion from larger type 'float4' to smaller type '__restrict min16float4', possible loss of data [-Wconversion] UATHelper: 打包 (Android (ASTC)): Interpolants.TangentToWorld0 = float4(InTangentToWorld0, 0); UATHelper: 打包 (Android (ASTC)): ^ UATHelper: 打包 (Android (ASTC)): /Engine/Private/LocalVertexFactoryCommon.ush:147:32: warning: conversion from larger type 'float4' to smaller type '__restrict min16float4', possible loss of data [-Wconversion] UATHelper: 打包 (Android (ASTC)): Interpolants.TangentToWorld2 = float4(InTangentToWorld2, InTangentToWorldSign); UATHelper: 打包 (Android (ASTC)): ^ UATHelper: 打包 (Android (ASTC)): /Engine/Private/LocalVertexFactory.ush:541:17: warning: conversion from larger type 'float3x3' to smaller type 'min16float3x3', possible loss of data [-Wconversion] UATHelper: 打包 (Android (ASTC)): min16float3x3 LocalToWorld = LWCToFloat3x3(GetInstanceData(Intermediates).LocalToWorld); UATHelper: 打包 (Android (ASTC)): ^ UATHelper: 打包 (Android (ASTC)): /Engine/Private/LocalVertexFactory.ush:542:15: warning: conversion from larger type 'float3' to smaller type 'min16float3', possible loss of data [-Wconversion] UATHelper: 打包 (Android (ASTC)): min16float3 InvScale = GetInstanceData(Intermediates).InvNonUniformScale; UATHelper: 打包 (Android (ASTC)): ^ UATHelper: 打包 (Android (ASTC)): /Engine/Private/LocalVertexFactory.ush:853:36: warning: conversion from larger type 'float' to smaller type 'min16float', possible loss of data [-Wconversion] UATHelper: 打包 (Android (ASTC)): Intermediates.TangentToWorldSign = TangentSign * GetInstanceData(Intermediates).DeterminantSign; UATHelper: 打包 (Android (ASTC)): ^ UATHelper: 打包 (Android (ASTC)): /Engine/Private/MobileBasePassVertexShader.usf:42:15: warning: conversion from larger type 'float3' to smaller type 'min16float3', possible loss of data [-Wconversion] UATHelper: 打包 (Android (ASTC)): min16float3 WorldPositionOffset = GetMaterialWorldPositionOffset(VertexParameters); UATHelper: 打包 (Android (ASTC)): ^ UATHelper: 打包 (Android (ASTC)): Struct member does not have MatrixStride set. UATHelper: 打包 (Android (ASTC)): Failed to compile default material /Engine/EngineMaterials/DefaultLightFunctionMaterial.DefaultLightFunctionMaterial! PackagingResults: Error: appError called: Fatal error: [File:D:\build\++UE5\Sync\Engine\Source\Runtime\Engine\Private\ShaderCompiler\ShaderCompiler.cpp] [Line: 4668] PackagingResults: Warning: conversion from larger type 'float4' to smaller type '__restrict min16float4', possible loss of data [-Wconversion] PackagingResults: Warning: conversion from larger type 'float4' to smaller type '__restrict min16float4', possible loss of data [-Wconversion] PackagingResults: Warning: conversion from larger type 'float3x3' to smaller type 'min16float3x3', possible loss of data [-Wconversion] PackagingResults: Warning: conversion from larger type 'float3' to smaller type 'min16float3', possible loss of data [-Wconversion] PackagingResults: Warning: conversion from larger type 'float' to smaller type 'min16float', possible loss of data [-Wconversion] PackagingResults: Warning: conversion from larger type 'float3' to smaller type 'min16float3', possible loss of data [-Wconversion] UATHelper: 打包 (Android (ASTC)): LogWindows: Error: begin: stack for UAT UATHelper: 打包 (Android (ASTC)): LogWindows: Error: === Critical error: === UATHelper: 打包 (Android (ASTC)): LogWindows: Error: UATHelper: 打包 (Android (ASTC)): LogWindows: Error: Fatal error: [File:D:\build\++UE5\Sync\Engine\Source\Runtime\Engine\Private\ShaderCompiler\ShaderCompiler.cpp] [Line: 4668] UATHelper: 打包 (Android (ASTC)): LogWindows: Error: /Engine/Private/LocalVertexFactoryCommon.ush:146:32: warning: conversion from larger type 'float4' to smaller type '__restrict min16float4', possible loss of data [-Wconversion] UATHelper: 打包 (Android (ASTC)): LogWindows: Error: Interpolants.TangentToWorld0 = float4(InTangentToWorld0, 0); UATHelper: 打包 (Android (ASTC)): LogWindows: Error: ^ UATHelper: 打包 (Android (ASTC)): LogWindows: Error: /Engine/Private/LocalVertexFactoryCommon.ush:147:32: warning: conversion from larger type 'float4' to smaller type '__restrict min16float4', possible loss of data [-Wconversion] UATHelper: 打包 (Android (ASTC)): LogWindows: Error: Interpolants.TangentToWorld2 = float4(InTangentToWorld2, InTangentToWorldSign); UATHelper: 打包 (Android (ASTC)): LogWindows: Error: ^ UATHelper: 打包 (Android (ASTC)): LogWindows: Error: /Engine/Private/LocalVertexFactory.ush:541:17: warning: conversion from larger type 'float3x3' to smaller type 'min16float3x3', possible loss of data [-Wconversion] UATHelper: 打包 (Android (ASTC)): LogWindows: Error: min16float3x3 LocalToWorld = LWCToFloat3x3(GetInstanceData(Intermediates).LocalToWorld); UATHelper: 打包 (Android (ASTC)): LogWindows: Error: ^ UATHelper: 打包 (Android (ASTC)): LogWindows: Error: /Engine/Private/LocalVertexFactory.ush:542:15: warning: conversion from larger type 'float3' to smaller type 'min16float3', possible loss of data [-Wconversion] UATHelper: 打包 (Android (ASTC)): LogWindows: Error: min16float3 InvScale = GetInstanceData(Intermediates).InvNonUniformScale; UATHelper: 打包 (Android (ASTC)): LogWindows: Error: ^ UATHelper: 打包 (Android (ASTC)): LogWindows: Error: /Engine/Private/LocalVertexFactory.ush:853:36: warning: conversion from larger type 'float' to smaller type 'min16float', possible loss of data [-Wconversion] UATHelper: 打包 (Android (ASTC)): LogWindows: Error: Intermediates.TangentToWorldSign = TangentSign * GetInstanceData(Intermediates).DeterminantSign; UATHelper: 打包 (Android (ASTC)): LogWindows: Error: ^ UATHelper: 打包 (Android (ASTC)): LogWindows: Error: /Engine/Private/MobileBasePassVertexShader.usf:42:15: warning: conversion from larger type 'float3' to smaller type 'min16float3', possible loss of data [-Wconversion] UATHelper: 打包 (Android (ASTC)): LogWindows: Error: min16float3 WorldPositionOffset = GetMaterialWorldPositionOffset(VertexParameters); UATHelper: 打包 (Android (ASTC)): LogWindows: Error: ^ UATHelper: 打包 (Android (ASTC)): LogWindows: Error: Struct member does not have MatrixStride set. UATHelper: 打包 (Android (ASTC)): LogWindows: Error: Failed to compile default material /Engine/EngineMaterials/DefaultLightFunctionMaterial.DefaultLightFunctionMaterial! UATHelper: 打包 (Android (ASTC)): LogWindows: Error: UATHelper: 打包 (Android (ASTC)): LogWindows: Error: UATHelper: 打包 (Android (ASTC)): LogWindows: Error: [Callstack] 0x00007fff00956a0e UnrealEditor-Engine.dll!UnknownFunction [] UATHelper: 打包 (Android (ASTC)): LogWindows: Error: [Callstack] 0x00007fff00954e77 UnrealEditor-Engine.dll!UnknownFunction [] UATHelper: 打包 (Android (ASTC)): LogWindows: Error: [Callstack] 0x00007ffefc6c0ba5 UnrealEditor-UnrealEd.dll!UnknownFunction [] UATHelper: 打包 (Android (ASTC)): LogWindows: Error: [Callstack] 0x00007ffefc7411fd UnrealEditor-UnrealEd.dll!UnknownFunction [] UATHelper: 打包 (Android (ASTC)): LogWindows: Error: [Callstack] 0x00007ffefc7518c7 UnrealEditor-UnrealEd.dll!UnknownFunction [] UATHelper: 打包 (Android (ASTC)): LogWindows: Error: [Callstack] 0x00007ffefc7511a5 UnrealEditor-UnrealEd.dll!UnknownFunction [] UATHelper: 打包 (Android (ASTC)): LogWindows: Error: [Callstack] 0x00007ffefc4af780 UnrealEditor-UnrealEd.dll!UnknownFunction [] UATHelper: 打包 (Android (ASTC)): LogWindows: Error: [Callstack] 0x00007ffefc4d16a3 UnrealEditor-UnrealEd.dll!UnknownFunction [] UATHelper: 打包 (Android (ASTC)): LogWindows: Error: [Callstack] 0x00007ff646b1b0ce UnrealEditor-Cmd.exe!UnknownFunction [] UATHelper: 打包 (Android (ASTC)): LogWindows: Error: [Callstack] 0x00007ff646b12688 UnrealEditor-Cmd.exe!UnknownFunction [] UATHelper: 打包 (Android (ASTC)): LogWindows: Error: [Callstack] 0x00007ff646b1296a UnrealEditor-Cmd.exe!UnknownFunction [] UATHelper: 打包 (Android (ASTC)): LogWindows: Error: [Callstack] 0x00007ff646b15680 UnrealEditor-Cmd.exe!UnknownFunction [] UATHelper: 打包 (Android (ASTC)): LogWindows: Error: [Callstack] 0x00007ff646b271b4 UnrealEditor-Cmd.exe!UnknownFunction [] UATHelper: 打包 (Android (ASTC)): LogWindows: Error: [Callstack] 0x00007ff646b296f2 UnrealEditor-Cmd.exe!UnknownFunction [] UATHelper: 打包 (Android (ASTC)): LogWindows: Error: [Callstack] 0x00007fff72077034 KERNEL32.DLL!UnknownFunction [] UATHelper: 打包 (Android (ASTC)): LogWindows: Error: [Callstack] 0x00007fff728226a1 ntdll.dll!UnknownFunction [] UATHelper: 打包 (Android (ASTC)): LogWindows: Error: UATHelper: 打包 (Android (ASTC)): LogWindows: Error: end: stack for UAT PackagingResults: Error: begin: stack for UAT PackagingResults: Error: === Critical error: === PackagingResults: Error: Fatal error: [File:D:\build\++UE5\Sync\Engine\Source\Runtime\Engine\Private\ShaderCompiler\ShaderCompiler.cpp] [Line: 4668] PackagingResults: Warning: conversion from larger type 'float4' to smaller type '__restrict min16float4', possible loss of data [-Wconversion] PackagingResults: Error: Interpolants.TangentToWorld0 = float4(InTangentToWorld0, 0); PackagingResults: Error: ^ PackagingResults: Warning: conversion from larger type 'float4' to smaller type '__restrict min16float4', possible loss of data [-Wconversion] PackagingResults: Error: Interpolants.TangentToWorld2 = float4(InTangentToWorld2, InTangentToWorldSign); PackagingResults: Error: ^ PackagingResults: Warning: conversion from larger type 'float3x3' to smaller type 'min16float3x3', possible loss of data [-Wconversion] PackagingResults: Error: min16float3x3 LocalToWorld = LWCToFloat3x3(GetInstanceData(Intermediates).LocalToWorld); PackagingResults: Error: ^ PackagingResults: Warning: conversion from larger type 'float3' to smaller type 'min16float3', possible loss of data [-Wconversion] PackagingResults: Error: min16float3 InvScale = GetInstanceData(Intermediates).InvNonUniformScale; PackagingResults: Error: ^ PackagingResults: Warning: conversion from larger type 'float' to smaller type 'min16float', possible loss of data [-Wconversion] PackagingResults: Error: Intermediates.TangentToWorldSign = TangentSign * GetInstanceData(Intermediates).DeterminantSign; PackagingResults: Error: ^ PackagingResults: Warning: conversion from larger type 'float3' to smaller type 'min16float3', possible loss of data [-Wconversion] PackagingResults: Error: min16float3 WorldPositionOffset = GetMaterialWorldPositionOffset(VertexParameters); PackagingResults: Error: ^ PackagingResults: Error: Struct member does not have MatrixStride set. PackagingResults: Error: Failed to compile default material /Engine/EngineMaterials/DefaultLightFunctionMaterial.DefaultLightFunctionMaterial! PackagingResults: Error: [Callstack] 0x00007fff00956a0e UnrealEditor-Engine.dll!UnknownFunction [] PackagingResults: Error: [Callstack] 0x00007fff00954e77 UnrealEditor-Engine.dll!UnknownFunction [] PackagingResults: Error: [Callstack] 0x00007ffefc6c0ba5 UnrealEditor-UnrealEd.dll!UnknownFunction [] PackagingResults: Error: [Callstack] 0x00007ffefc7411fd UnrealEditor-UnrealEd.dll!UnknownFunction [] PackagingResults: Error: [Callstack] 0x00007ffefc7518c7 UnrealEditor-UnrealEd.dll!UnknownFunction [] PackagingResults: Error: [Callstack] 0x00007ffefc7511a5 UnrealEditor-UnrealEd.dll!UnknownFunction [] PackagingResults: Error: [Callstack] 0x00007ffefc4af780 UnrealEditor-UnrealEd.dll!UnknownFunction [] PackagingResults: Error: [Callstack] 0x00007ffefc4d16a3 UnrealEditor-UnrealEd.dll!UnknownFunction [] PackagingResults: Error: [Callstack] 0x00007ff646b1b0ce UnrealEditor-Cmd.exe!UnknownFunction [] PackagingResults: Error: [Callstack] 0x00007ff646b12688 UnrealEditor-Cmd.exe!UnknownFunction [] PackagingResults: Error: [Callstack] 0x00007ff646b1296a UnrealEditor-Cmd.exe!UnknownFunction [] PackagingResults: Error: [Callstack] 0x00007ff646b15680 UnrealEditor-Cmd.exe!UnknownFunction [] PackagingResults: Error: [Callstack] 0x00007ff646b271b4 UnrealEditor-Cmd.exe!UnknownFunction [] PackagingResults: Error: [Callstack] 0x00007ff646b296f2 UnrealEditor-Cmd.exe!UnknownFunction [] PackagingResults: Error: [Callstack] 0x00007fff72077034 KERNEL32.DLL!UnknownFunction [] PackagingResults: Error: [Callstack] 0x00007fff728226a1 ntdll.dll!UnknownFunction [] PackagingResults: Error: end: stack for UAT UATHelper: 打包 (Android (ASTC)): Took 674.0243639s to run UnrealEditor-Cmd.exe, ExitCode=3 UATHelper: 打包 (Android (ASTC)): ERROR: Cook failed. UATHelper: 打包 (Android (ASTC)): (see C:\Users\Administrator\AppData\Roaming\Unreal Engine\AutomationTool\Logs\D+UE5+UE_5.1\Log.txt for full exception trace) UATHelper: 打包 (Android (ASTC)): AutomationTool executed for 0h 11m 45s UATHelper: 打包 (Android (ASTC)): AutomationTool exiting with ExitCode=25 (Error_UnknownCookFailure) UATHelper: 打包 (Android (ASTC)): BUILD FAILED PackagingResults: Error: Cook failed. 分析打包失败原因
06-26
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值