更新“Shader-like”代码以解释形状旋转时的颜色变化

问题描述 投票:0回答:0

我想知道是否有人可以帮助理解我在旋转对象时更新下面的代码需要做什么。我有一些我继承的代码(该死的家伙刚刚退出)并且我被要求更新它以解决形状 3D 旋转时重新着色的问题。我试图理解这一点,但 3D 及其数学有点超出我的范围 - 我只是没有完全理解它。

该代码旨在模仿 Microsoft Office 在应用灯光和材料时如何为纯色形状重新着色。在任何较新的 Microsoft Office 产品(如 PowerPoint)中,您都可以设置灯光、材料和 3D 旋转。所有 3 个都会导致实心填充颜色发生变化。这是他们设置的地方:

我继承的代码如下。我猜它可以被认为是一个“着色器”。如果我标记了错误的组,我提前道歉。

Public Function CreateVertexColorSimple() As Color
        '--------------------------------------------
        '/ / / / / / MATERIAL DETAILS / / / / / / / / 
        '--------------------------------------------
        Dim materialEmmisiveColor As New Color(0, 0, 0, 1) 'black
        Dim materialAmbientColor As New Color(0.2667, 0.4471, 0.7686, 1) 'RGB = 68,114,196. A blue
        'materialAmbientColor is the color of the shape in PowerPoint
        Dim materialSpecularColor As New Color(0.3, 0.3, 0.3, 1) ' RGB = 76.5. A light gray
        Dim materialSpecularPower As Integer = 8
        Dim materialDiffuseColor As Color = materialAmbientColor

        '--------------------------------------------
        '/ / / / / / LIGHT DETAILS / / / / / / / / /
        '--------------------------------------------
        'color is RGB = 214.2
        Dim light1 As (Color As Color, Direction As Vector3) = (New Color(0.84, 0.84, 0.84, 1), New Vector3(0.5266, -0.4089, -0.7454))

        'color is RGB = 76.5
        Dim light2 As (Color As Color, Direction As Vector3) = (New Color(0.3, 0.3, 0.3, 1), New Vector3(-0.8983, 0.2365, -0.3704))

        'color is RGB = 63.75
        Dim ambientLightColor As New Color(0.25, 0.25, 0.25, 1)
        Dim lights As New List(Of (Color As Color, Direction As Vector3)) From {light1, light2}

        '--------------------------------------------
        '/ / / / / / INITIAL SETTINGS / / / / / / /
        '--------------------------------------------
        Dim baseColor As Color = materialEmmisiveColor 'black
        baseColor += ambientLightColor * materialAmbientColor
        baseColor.A = materialDiffuseColor.A

        Dim diffuseColor As Color = baseColor
        Dim specularColor As New Color(0, 0, 0, 1) 'black

        'Front face of cube, no rotation
        Dim vertexNormal As New Vector3(0, 0, 1)
        Dim viewDirection As New Vector3(0, 0, -1)

        For Each light In lights
            Dim lightDirection As Vector3 = light.Direction

            'diffuse
            Dim diffuseIllumination As Single = -Vector3.Dot(vertexNormal, lightDirection)
            diffuseIllumination = Clamp(diffuseIllumination, 0.0F, 1.0F)
            diffuseColor.RGB += diffuseIllumination * light.Color.RGB * materialDiffuseColor.RGB

            'specular Phong highlight
            Dim reflectionVector As Vector3 = viewDirection - 2.0F * vertexNormal * Vector3.Dot(vertexNormal, viewDirection)
            Dim specularIllumination As Single = -Vector3.Dot(lightDirection, reflectionVector)
            If specularIllumination > 0 Then
                Dim attenuatedSpecularIllumination As Single = Math.Pow(specularIllumination, materialSpecularPower)
                If attenuatedSpecularIllumination > 0.001F Then
                    specularColor.RGB += attenuatedSpecularIllumination * light.Color.RGB * materialSpecularColor.RGB
                End If
            End If

        Next

        Dim finalColor As Color = diffuseColor + specularColor

        Return finalColor
    End Function

当 Material = Warm Matte 和 Lighting = Two Point(在 PowerPoint 中设置)时,这适用于将现有形状重新着色为新颜色。但是当我旋转形状时,颜色会发生巨大变化,我可以很清楚这段代码中需要更新什么——是

VertexNormal
吗?是每盏灯的
LightDirection
吗?我不认为这是
ViewDirection
,但我可能是错的。

所以在我的研究中,我发现底层的 3D 引擎使用“球坐标”,如下所述:

表示物体在物体表面的位置和方向 单位球体(以原点为中心,半径为 1.0 的球体)

经度和纬度描述球体表面的位置, 而革命描述了物体在表面上的方向 与球体表面相切的球体。这个坐标系是 适合表示相机和灯光的位置和方向 相对于锚点。相机可以放在球体的任何位置 表面(由纬度/经度定义的点)。相机有一个天然的 “向上”的方向。如果相机直视中心 球体(身份),它可以原地旋转(改变它的“向上” 方向)完整的 360 度。

0的纬度是y为0的赤道。纬度垂直环绕 整个球体。 90度的纬度直接落在 顶杆;纬度 270 落在底极上;的纬度 360 结束回到赤道。

0度和360度的经度标记单元的最前面点 球体,其中 x=0、y=0、z=1。从北方俯视球体 极点,经线绕球体逆时针旋转。
与正纬度同向旋转0点 线和旋转角度相对于逆时针旋转 球面。在赤道上的任何一点(纬度 0), 旋转0是指向顶极的方向; 向底杆旋转180点;和革命 90度和270度分别指向左右。

基于此,我已故的同事开始了 3D 旋转的道路:

Function GetNewRotatedPosition() As Vector3
    Dim longitude As Double = 45 'the rotationX
    Dim latitude As Double = 45 'the rotationY
    Const HalfPi As Single = Math.PI / 2
    Dim rotationX As Double = (longitude * Math.PI / 180) + HalfPi
    Dim rotationY As Double = HalfPi - (latitude * Math.PI / 180)

    Dim position As New Vector3

    position.X = Math.Cos(rotationY) * Math.Cos(rotationX)
    position.Y = Math.Sin(rotationY)
    position.Z = Math.Cos(rotationY) * Math.Sin(rotationX)

    Return position
End Function

但我不知道如何使用它来更新上面的

CreateVertexColorSimple
代码。请参阅下面具有不同属性的相同形状的示例。这是我正在寻找的最后两个(#3 和#4)如何用上面的代码解释它们的颜色变化。

有人有什么建议吗?

3d shader
© www.soinside.com 2019 - 2024. All rights reserved.