Android Lesson Two: Ambient and Diffuse Lighting

2022-04-13 Ambient Light & Proximity Sensor 光感和距离传感器 STK3311X调试记录 RK3566 Android11平台 一、原理图,接口比较简单,就是I2C。 二、光感用轮询方式,距离用中断方式。代码。 1、dts配置 ls_stk3x1x: light@48 { compatible = "ls_stk3x1x"; status = "okay"; reg = <0x48>; type = <SENSOR_TYPE_LIGHT>; irq_enable = <0>; als_threshold_high = <100>; als... 阅读详情

原文链接地址:http://www.learnopengles.com/android-lesson-two-ambient-and-diffuse-lighting/

 

Welcome to the second tutorial for Android. In this lesson, we’re going to learn how to implementLambertian reflectance using shaders, otherwise known as your standard diffuse lighting. In OpenGL ES 2, we need to implement our own lighting algorithms, so we will learn how the math works and how we can apply it to our scenes.

Assumptions and prerequisites

Each lesson in this series builds on the lesson before it. Before we begin, please review the first lesson as this lesson will build upon the concepts introduced there.

What is light?lessontwo

A world without lighting would be a dim one, indeed. Without light, we would not even be able to perceive the world or the objects that lie around us, except via the other senses such as sound and touch. Light shows us how bright or dim something is, how near or far it is, and what angle it lies at.

In the real world, what we perceive as light is really the aggregation of trillions of tiny particles called photons, which fly out of a light source, bounce around thousands or millions of times, and eventually reach our eye where we perceive it as light.

How can we simulate the effects of light via computer graphics? There are two popular ways to do it:ray tracing, andrasterisation. Ray tracing works by mathematically tracing actual rays of light and seeing where they end up. This technique gives very accurate and realistic results, but the downside is that simulating all of those rays is very computationally expensive, and usually too slow for real-time rendering. Due to this limitation, most real-time computer graphics use rasterisation instead, which simulates lighting by approximating the result. Given the realism of recent games, rasterisation can also look very nice, and is fast enough for real-time graphics even on mobile phones. Open GL ES is primarily a rasterisation library, so this is the approach we will focus on.

The different kinds of light

It turns out that we can abstract the way that light works and come up with three basic types of lighting:

Ambient lighting. Source: http://www.geograph.org.uk/photo/774138

Ambient lighting.

 

Ambient lighting

This is a base level of lighting that seems to pervade an entire scene. It is light that doesn’t appear to come from any light source in particular because it has bounced around so much before reaching you. This type of lighting can be experienced outdoors on an overcast day, or indoors as the cumulative effect of many different light sources. Instead of calculating all of the individual lights, we can just set a base light level for the object or scene.

An example of ambient and diffuse lighting. Source: http://commons.wikimedia.org/wiki/File:Wikibooks_povray_colors_transparent_sphere.gif

An example of ambient and diffuse lighting.

 

Diffuse lighting

This is light that reaches your eye after bouncing directly off of an object. The illumination level of the object varies with its angle to the lighting. Something facing the light head on is lit more brightly than something facing the light at an angle. Also, we perceive the object to be the same brightness no matter which angle we are at relative to the object. This is otherwise known asLambert’s cosine law. Diffuse lighting or Lambertian reflectance is common in everyday life and can be easily seen on a white wall lit up by an indoor light.

Specular highlight. Source: http://en.wikipedia.org/wiki/File:Specular_highlight.jpg

An example of specular highlights.

 

Specular lighting

Unlike diffuse lighting, specular lighting changes as we move relative to the object. This gives “shininess” to the object and can be seen on “smoother” surfaces such as glass and other shiny objects.

Simulating light

Just as there are three main types of light in a 3D scene, there are also three main types of light sources: directional, point, and spotlight. These can also be easily seen in everyday life.

Brightly lit landscape. Source: http://upload.wikimedia.org/wikipedia/commons/2/2a/KaliGandaki.jpg

A brightly lit landscape.

 

Directional lighting

Directional lighting usually comes from a bright source that is so far away that it lights up the entire scene evenly and to the same brightness. This light source is the simplest type as the light is the same strength and direction no matter where you are in the scene.

Point light. Source: http://commons.wikimedia.org/wiki/File:Flare_0.jpg

An example of point lights.

 

Point lighting

Point lights can be added to a scene in order to give more varied and realistic lighting. The illumination of a point lightfalls off with distance, and its light rays travel out in all directions with the point light at the center.

Spotlight. Source: http://www.flickr.com/photos/trektrack/24583555/

Spotlight.

 

Spot lighting

In addition to the properties of a point light, spot lights also have the direction of light attenuated, usually in the shape of a cone.

The math

In this lesson, we’re going to be looking at ambient lighting and diffuse lighting coming from a point source.

Ambient lighting

Ambient lighting is really indirect diffuse lighting, but it can also be thought of as a low-level light which pervades the entire scene. If we think of it that way, then it becomes very easy to calculate:

final color = material color * ambient light color 

 

For example, let’s say our object is red and our ambient light is a dim white. Let’s assume that we store color as an array of three colors: red, green, and blue, using theRGB color model:

final color = {1, 0, 0} * {0.1, 0.1, 0.1} = {0.1, 0.0, 0.0}

 

The final color of the object will be a dim red, which is what you’d expect if you had a red object illuminated by a dim white light. There is really nothing more to basic ambient lighting than that, unless you want to get into more advanced lighting techniques such as radiosity.

Diffuse lighting – point light source

For diffuse lighting, we need to add attenuation and a light position. The light position will be used to calculate the angle between the light and the surface, which will affect the surface’s overall level of lighting. It will also be used to calculate the distance between the light and the surface, which determines the strength of the light at that point.

Step 1: Calculate the lambert factor.

The first major calculation we need to make is to figure out the angle between the surface and the light. A surface which is facing the light straight-on should be illuminated at full strength, while a surface which is slanted should get less illumination. The proper way to calculate this is by using Lambert’s cosine law. If we have two vectors, one being from the light to a point on the surface, and the second being asurface normal (if the surface is a flat plane, then the surface normal is a vector pointing straight up, or orthogonal to that surface), then we can calculate the cosine by first normalizing each vector so that it has a length of one, and then by calculating thedot product of the two vectors. This is an operation that can easily be done via OpenGL ES 2 shaders.

Let’s call this the lambert factor, and it will have a range of between0 and1.

light vector = light position - object position cosine = dot product(object normal, normalize(light vector)) lambert factor = max(cosine, 0)
 

Fitst we calculate the light vector by subtracting the object position from the light position. Then we get the cosine by doing a dot product between the object normal and the light vector. We normalize the light vector, which means to change its length so it has a length of one. The object normal should already have a length of one. Taking the dot product of two normalized vectors gives you the cosine between them. Because the dot product can have a range of-1 to1, we clamp it to a range of 0 to 1.

Here’s an example with an flat plane at the origin and the surface normal pointing straight up toward the sky. The light is positioned at {0, 10, -10}, or 10 units up and 10 units straight ahead. We want to calculate the light at the origin.

light vector = {0, 10, -10} - {0, 0, 0} = {0, 10, -10} object normal = {0, 1, 0}

In plain English, if we move from where we are along the light vector, we reach the position of the light. To normalize the vector, we divide each component by the vector length:

light vector length = square root(0*0 + 10*10 + -10*-10) = square root(200) = 14.14 

Then we calculate the dot product:

dot product({0, 1, 0}, {0, 0.707, -0.707}) = (0 * 0) + (1 * 0.707) + (0 * -0.707) = 0 + 0.707 + 0 = 0.707 
 
1
lambert factor = max(0.707, 0) = 0.707

OpenGL ES 2′s shading language has built in support for some of these functions so we don’t need to do all of the math by hand, but it can still be useful to understand what is going on.

Step 2: Calculate the attenuation factor.

Next, we need to calculate the attenuation. Real light attenuation from a point light source follows theinverse square law, which can also be stated as:

luminosity = 1 / (distance * distance) 

Going back to our example, since we have a distance of 14.14, here is what our final luminosity looks like:

luminosity = 1 / (14.14*14.14) = 1 / 200 = 0.005 

As you can see, the inverse square law can lead to a strong attenuation over distance. This is how light from a point light source works in the real world, but since our graphics displays have a limited range, it can be useful to dampen this attenuation factor so we still get realistic lighting without things looking too dark.

Step 3: Calculate the final color.

Now that we have both the cosine and the attenuation, we can calculate our final illumination level:

final color = material color * (light color * lambert factor * luminosity) 

Going with our previous example of a red material and a full white light source, here is the final calculation:

final color = {1, 0, 0} * ({1, 1, 1} * 0.707 * 0.005}) = {1, 0, 0} * {0.0035, 0.0035, 0.0035} = {0.0035, 0, 0} 

To recap, for diffuse lighting we need to use the angle between the surface and the light as well as the distance between the surface and the light in order to calculate the final overall diffuse illumination level. Here are the steps:

//Step one 
light vector = light position - object position
cosine = dot product(object normal, normalize(light vector))
lambert factor = max(cosine, 0)
  
//Step two 
luminosity = 1 / (distance * distance)
  
//Step three 
final color = material color * (light color * lambert factor * luminosity) 
Putting this all into OpenGL ES 2 shaders
The vertex shader
  finalString vertexShader = 
    "uniform mat4 u_MVPMatrix;      \n"    // A constant representing the combined model/view/projection matrix.
  +"uniform mat4 u_MVMatrix;       \n"     // A constant representing the combined model/view matrix. 
  +"uniform vec3 u_LightPos;       \n"     // The position of the light in eye space. 
 
  +"attribute vec4 a_Position;     \n"     // Per-vertex position information we will pass in. 
  +"attribute vec4 a_Color;        \n"     // Per-vertex color information we will pass in. 
  +"attribute vec3 a_Normal;       \n"     // Per-vertex normal information we will pass in. 
 
  +"varying vec4 v_Color;          \n"     // This will be passed into the fragment shader. 
 
  +"void main()                    \n"     // The entry point for our vertex shader. 
  +"{                              \n"
// Transform the vertex into eye space.
  +"   vec3 modelViewVertex = vec3(u_MVMatrix * a_Position);              \n"
// Transform the normal's orientation into eye space.
  +"   vec3 modelViewNormal = vec3(u_MVMatrix * vec4(a_Normal, 0.0));     \n"
// Will be used for attenuation.
  +"   float distance = length(u_LightPos - modelViewVertex);             \n"
// Get a lighting direction vector from the light to the vertex.
  +"   vec3 lightVector = normalize(u_LightPos - modelViewVertex);        \n"
// Calculate the dot product of the light vector and vertex normal. If the normal and light vector are
// pointing in the same direction then it will get max illumination.
  +"   float diffuse = max(dot(modelViewNormal, lightVector), 0.1);       \n"
// Attenuate the light based on distance.
  +"   diffuse = diffuse * (1.0 / (1.0 + (0.25 * distance * distance)));  \n"
// Multiply the color by the illumination level. It will be interpolated across the triangle.
  +"   v_Color = a_Color * diffuse;                                       \n"
// gl_Position is a special variable used to store the final position.
// Multiply the vertex by the matrix to get the final point in normalized screen coordinates.
  +"   gl_Position = u_MVPMatrix * a_Position;                            \n"
  +"}                                                                     \n";

There is quite a bit going on here. We have our combined model/view/projection matrix as inlesson one, but we’ve also added a model/view matrix. Why? We will need this matrix in order to calculate the distance between the position of the light source and the position of the current vertex. For diffuse lighting, it actually doesn’t matter whether you use world space (model matrix) or eye space (model/view matrix) so long as you can calculate the proper distances and angles.

We pass in the vertex color and position information, as well as the surface normal. We will pass the final color to the fragment shader, which will interpolate it between the vertices. This is also known asGouraud shading.

Let’s look at each part of the shader to see what’s going on:

 // Transform the vertex into eye space.
  +"   vec3 modelViewVertex = vec3(u_MVMatrix * a_Position);              \n" 

Since we’re passing in the position of the light in eye space, we convert the current vertex position to a coordinate in eye space so we can calculate the proper distances and angles.

 // Transform the normal's orientation into eye space.
  +"   vec3 modelViewNormal = vec3(u_MVMatrix * vec4(a_Normal, 0.0));     \n" 

We also need to transform the normal’s orientation. Here we are just doing a regular matrix multiplication like with the position, but if the model or view matrices have been scaled or skewed, this won’t work: we’ll actually have to undo the effect of the skew or scale by multiplying the normal by the transpose of the inverse of the original matrix.This website best explains why we have to do this.

// Will be used for attenuation.
  +"   float distance = length(u_LightPos - modelViewVertex);             \n" 

As shown before in the math section, we need the distance in order to calculate the attenuation factor.

// Get a lighting direction vector from the light to the vertex.
  +"   vec3 lightVector = normalize(u_LightPos - modelViewVertex);        \n" 

We also need the light vector to calculate the Lambertian reflectance factor.

// Calculate the dot product of the light vector and vertex normal. If the normal and light vector are
// pointing in the same direction then it will get max illumination.
  +"   float diffuse = max(dot(modelViewNormal, lightVector), 0.1);       \n" 

This is the same math as above in the math section, just done in an OpenGL ES 2 shader. The 0.1 at the end is just a really cheap way of doing ambient lighting (the value will be clamped to a minimum of 0.1).

// Attenuate the light based on distance.
  +"   diffuse = diffuse * (1.0 / (1.0 + (0.25 * distance * distance)));  \n" 

The attenuation math is a bit different than above in the math section. We scale the square of the distance by 0.25 to dampen the attenuation effect, and we also add 1.0 to the modified distance so that we don’t get oversaturation when the light is very close to an object (otherwise, when the distance is less than one, this equation will actually brighten the light instead of attenuating it).

// Multiply the color by the illumination level. It will be interpolated across the triangle.
  +"   v_Color = a_Color * diffuse;                                       \n"
// gl_Position is a special variable used to store the final position.
// Multiply the vertex by the matrix to get the final point in normalized screen coordinates.
  +"   gl_Position = u_MVPMatrix * a_Position;                            \n" 

Once we have our final light color, we multiply it by the vertex color to get the final output color, and then we project the position of this vertex to the screen.

The pixel shader
final String fragmentShader = 
  "precision mediump float;       \n"    // Set the default precision to medium. We don't need as high of a
                                          // precision in the fragment shader.
+ "varying vec4 v_Color;          \n"    // This is the color from the vertex shader interpolated across the
                                          // triangle per fragment.
+ "void main()                    \n"    // The entry point for our fragment shader. 
+ "{                              \n"
+ "   gl_FragColor = v_Color;     \n"    // Pass the color directly through the pipeline. 
+ "}                              \n";

Because we are calculating light on a per-vertex basis, our fragment shader looks the same as it did inthe first lesson — all we do is pass through the color directly through. In the next lesson, we’ll look at per-pixel lighting.

Per-Vertex versus per-pixel lighting

In this lesson we have focused on implementing per-vertex lighting. For diffuse lighting of objects with smooth surfaces, such as terrain, or for objects with many triangles, this will often be good enough. However, when your objects don’t contain many vertices (such as our cubes in this example program) or have sharp corners, vertex lighting can result in artifacts as the light level is linearly interpolated across the polygon; these artifacts also become much more apparent when specular highlights are added to the image. More can be seen at the Wiki article on Gouraud shading.

An explanation of the changes to the program

Besides the addition of per-vertex lighting, there are other changes to the program. We’ve switched from displaying a few triangles to a few cubes, and we’ve also added utility functions to load in the shader programs. There are also new shaders to display the position of the light as a point, as well as other various small changes.

Construction of the cube

In lesson one, we packed both position and color attributes into the same array, but OpenGL ES 2 also lets us specify these attributes in seperate arrays:

// X, Y, Z 
final float[] cubePositionData = 
{ 
        // In OpenGL counter-clockwise winding is default. This means that when we look at a triangle,
        // if the points are counter-clockwise we are looking at the "front". If not we are looking at
        // the back. OpenGL has an optimization where all back-facing triangles are culled, since they
        // usually represent the backside of an object and aren't visible anyways.
 
        // Front face
        -1.0f,1.0f, 1.0f,
        -1.0f, -1.0f,1.0f, 
        1.0f,1.0f, 1.0f,
        -1.0f, -1.0f,1.0f, 
        1.0f, -1.0f,1.0f, 
        1.0f,1.0f, 1.0f,
        ...
 
// R, G, B, A
final float[] cubeColorData = 
{ 
        // Front face (red)
        1.0f,0.0f, 0.0f,1.0f, 
        1.0f,0.0f, 0.0f,1.0f, 
        1.0f,0.0f, 0.0f,1.0f, 
        1.0f,0.0f, 0.0f,1.0f, 
        1.0f,0.0f, 0.0f,1.0f, 
        1.0f,0.0f, 0.0f,1.0f, 
        ...
New OpenGL flags

We have also enabled culling and the depth buffer via glEnable() calls:

// Use culling to remove back faces.
GLES20.glEnable(GLES20.GL_CULL_FACE);
 
// Enable depth testing
GLES20.glEnable(GLES20.GL_DEPTH_TEST); 

As an optimization, you can tell OpenGL to eliminate triangles that are on the back side of an object. When we defined our cube, we also defined the three points of each triangle so that they are counter-clockwise when looking at the “front” side. When we flip the triangle around so we’re looking at the “back” side, the points then appear clockwise. You can only ever see three sides of a cube at the same time so this optimization tells OpenGL to not waste its time drawing the back sides of triangles.

Later when we draw transparent objects we may want to turn culling back off, as then it will be possible to see the back sides of objects.

We’ve also enabled depth testing. If you always draw things in order from back to front then depth testing is not strictly necessary, but by enabling it not only do you not need to worry about the draw order (although rendering can be faster if you draw closer objects first), but some graphics cards will also make optimizations which can speed up rendering by spending less time drawing pixels that will be drawn over anyways.

Changes in loading shader programs

Because the steps to loading shader programs in OpenGL are mostly the same, these steps can easily be refactored into a separate method. We’ve also added the following calls to retrieve debug info, in case the compilation/link fails:

GLES20.glGetProgramInfoLog(programHandle);
GLES20.glGetShaderInfoLog(shaderHandle);
Vertex and shader program for the light point

There is a new vertex and shader program specifically for drawing the point on the screen that represents the current position of the light:

// Define a simple shader program for our point.
final String pointVertexShader = 
    "uniform mat4 u_MVPMatrix;      \n"
  +"attribute vec4 a_Position;     \n"
  +"void main()                    \n"
  +"{                              \n"
  +"   gl_Position = u_MVPMatrix   \n"
  +"               * a_Position;   \n"
  +"   gl_PointSize = 5.0;         \n"
  +"}                              \n";
 
final String pointFragmentShader = 
    "precision mediump float;       \n"
  +"void main()                    \n"
  +"{                              \n"
  +"   gl_FragColor = vec4(1.0,    \n"
  +"   1.0, 1.0, 1.0);             \n"
  +"}                              \n";

This shader is similar to the simple shader from the first lesson. There’s a new property, gl_PointSize which we hard-code to 5.0; this is the output point size in pixels. It’s used when we draw the point using GLES20.GL_POINTS as the mode. We’ve also hard-coded the output color to white.

Further Exercises
  • Try removing the “oversaturation protection” and see what happens.
  • There is a flaw with the way the ambient lighting is done. Can you spot what it is?
  • What happens if you add a gl_PointSize to the cube shader and draw it using GL_POINTS?
Further Reading

The further reading section above was an invaluable resource to me while writing this tutorial, so I highly recommend reading them for more information and explanations.

Android5.1 背光控制分析 本文主要讲述android5.1系统对背光的处理,从初始化到点击自动背光模式再到UI的同步处理,文章分为三点讲述:1.背光的初始化2.自动背光的调用过程:从点击setting中自动调节亮度开始3.systemUI和setting对背光模式的同步一:初始化1.1控制背光服务的启动大部分的服务的起点都在systemserver,背光的服务也不例外。首先启动一些基础的服务:private void ru... 阅读详情

相关推荐

Android7.1 亮度自动调节

1、代码主要涉及到frameworks/base/services/core/java/com/android/server/display 目录下的AutomaticBrightnessController.java。 2、AutomaticBrightnessController.java中的一些变量 mScreenAutoBrightness:屏幕亮度级别是由自动亮度算法决定的,实际的亮

Kitty_Landon的专栏 1万+

Android 8.1 DisplayPowerController(五) 自动调节亮度(2)——算法

作者:FightFightFight 来源:优快云 原文:https://blog.youkuaiyun.com/FightFightFight/article/details/83718273 在上一篇文章中,对自动背光的流程做了总结,在本篇中,将对自动背光涉及到的一些算法进行分析总结。 1.采集光强缓冲区 AmbientLightRingBuffer类是一个用于存储采集到的光照强度和对应时间点...

sdkdlwk的博客 2697

RK3572-Android16-记录一次OTA升级失败解决方案

这里记录一次解决RK3576 Android16 OTA 用Recovery 升级失败的一次解决案例,将部分经验作为总结。本次OTA升级耗时了几天,最终是RK给出的解决方案,再加上经验来解决了其它部分问题新平台,高一点的Android版本,可能本身有bug,多请教平台来,不要蒙着干,干不出来的。

十年饮冰,难凉热血 134

光线追踪(RayTracing)算法理论与实践(一)入门

提要 本文先介绍光线追踪的理论,然后着重一步一步来搭建渲染场景,从最基本的向量类开始.采用的语言是c++,利用面向对象的思想,一些基础的线性代数和空间几何的知识也会用到,编程的框架用的是GLFW,渲染用到的是OpenGL。 原理 光线追踪,简单地说,就是从摄影机的位置,通过影像平面上的像素位置(比较正确的说法是取样(sampling)位置),发射一束光线到场景,...

weixin_34233421的博客 2134

ConnectionResetError 10054 根因分析与全链路防御指南

ConnectionResetError(错误码10054)是TCP协议中服务端主动发送RST包导致的强制断连,本质并非网络连接失败,而是服务端基于空闲超时、连接满载、TLS协商失败等策略做出的确定性终止决策。理解其底层原理有助于跳出‘重试’误区,转向连接生命周期管理。该错误高频出现在HTTP长连接、WebSocket、第三方API对接等场景,尤其在Nginx反向代理、负载均衡器(如AWS ALB)、WAF设备及内核conntrack机制下极易触发。本文结合Wireshark抓包分析、客户端心跳保鲜、协议指

weixin_30225755的博客 639

2024最新指南:如何用Python批量下载Sentinel-2数据(附避坑清单)

本文提供2024年最新Python批量下载Sentinel-2遥感数据的完整指南,涵盖环境配置、API准备、核心下载流程实现及实战避坑清单。通过智能查询器、断点续传下载器等实用工具,帮助用户高效获取遥感数据,避免常见网络问题和数据完整性验证失败。

silver的专栏 619

android修改自动背光,自动背光算法-Android 8.1

本文基于工作中自动背光笔记扩充了下,记录下自动背光算法。基于Android 8.1, 代码可参看 http://androidxref.com/8.1.0_...Android 9加入了所谓的机器学习算法,根据用户调节时亮度和光感重新生成曲线,自动背光时的滑动条不再是调节adjustment值,暂时不想写了。。。Android 10简单看了下,加入了对foreground应用的微调支持,暂时不想写...

weixin_30771489的博客 2501

COMSOL仿真避坑指南:列管反应器模拟中多孔介质与化学反应设置的5个常见错误

本文详细解析了COMSOL仿真中列管反应器模拟的5个常见错误,包括多孔介质模型选择、化学反应接口配置、对流扩散方程处理、薄层热阻设置及网格独立性验证。特别针对多孔介质与化学反应设置的误区,提供了实用的判断标准和修正方法,帮助工程师避免计算偏差,提升仿真精度。

weixin_29597551的博客 324

Android 系统7.0上 屏幕背光流程分析

Android 系统 屏幕背光流程分析(未完待续) 概述 自动背光初始化 自动背光的初始化 概述最近关于自动背光的问题报的比较多,多是背光不灵敏以及背光调节不正常的问题,并且自动背光也是直接和用户交互的一个模块,对于用户体验有着最直观的影响,所以在此分析一下关于自动背光模块的处理逻辑,以及小米对于自动背光所作的优化,关于后期优化方案,也希望大家能多多建议。自动背光在android系统中属于displ

风花散却隽世间,雪月寥落化雨田 1万+

STM32驱动MG996R舵机的PWM控制与闭环原理

舵机是一种典型的模拟闭环伺服系统,其核心是通过电位器反馈实现角度位置的自动校正。工作原理基于负反馈控制:目标PWM脉宽决定期望角度,电位器输出实时反馈实际角度,控制电路计算偏差并驱动电机消除误差。该机制赋予舵机强带载能力与抗干扰性,是机器人、云台、智能执行器等场景的关键执行单元。在嵌入式开发中,STM32通过定时器生成标准20ms周期、0.5–2.5ms脉宽的PWM信号,需严格遵循电气规范,并解决PA15引脚SWJ复用冲突、定时器重映射及CCR精度计算等关键问题。本文深入解析MG996R舵机控制全流程,涵盖

weixin_42600407的博客 563

FoundationPose复现及Realsense应用

FoundationPose是一个统一的基础模型,用于6D对象姿态估计和跟踪,支持基于模型和无模型的设置。在测试时可以立即应用于未见过的新对象,无需微调,只要给出其CAD模型,或者捕获少量RGBD参考图像。得益于统一框架,下游姿态估计模块在两种3D模型设置中都是相同的,当没有CAD模型时,使用神经隐式表示进行高效的新视角合成。通过大规模合成训练,辅以大型语言模型(LLM)、一种基于transformer的新架构和对比学习公式,实现了强大的泛化能力。

m0_56661101的博客 1万+

android 8.1自动背光随笔

本文简单梳理自己对自动背光涉及算法理解主要类:AutomaticBrightnessController.javaDisplayPowerController.javaSpline.java1.AutomaticBrightnessController中注册SensorEventListener监听,LightSensor上报光照值回调onSensorChanged();对上报的光照值有以下两个方...

mafei19870124的专栏 2101

抖音风控参数‘bd-ticket-guard-client-data’深度解析:从X.509证书到请求签名的完整链路

本文深度解析抖音风控参数‘bd-ticket-guard-client-data’的技术实现,从X.509证书体系到请求签名的完整安全链路。通过Python代码示例,揭示证书生成、签名算法及票据封装等核心机制,帮助开发者理解现代平台风控系统的多层防御架构设计。

weixin_42525738的博客 433

Android Visualizer 实战:把声音画出来

是系统提供的音频效果(AudioEffect)之一。它挂在音频链路上,,把数据回吐给你——画波形、画频谱、做响度表。

Android的专栏 294

最小路径和——动态规划求解(Java实现)

最小路径和——动态规划求解(Java实现) 题目: 给定一个包含非负整数的 m x n 网格,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。 说明:每次只能向下或者向右移动一步。 示例: 输入: [ [1,3,1], [1,5,1], [4,2,1] ] 输出: 7 解释: 因为路径 1→3→1→1→1 的总和最小。 这题和机器人走路的思路类似,就是状态方程有所不同,...

weixin_43395911的博客 895

【实战】小红书笔记爬虫终极指南:模拟滑动加载,抓取图文(2026最新版)

小红书作为国内最大的生活方式分享社区,每天产生海量的图文笔记。对于数据分析、市场调研、竞品分析等需求,爬取小红书公开笔记成为一项常见任务。然而,小红书的反爬机制日益升级——接口加密、动态Token、滑动验证、设备指纹……本文将深入剖析小红书Web端和App端的爬取技术,手把手教你用Python实现模拟滑动加载、自动抓取图文笔记的完整爬虫系统。全文包含大量代码、原理分析和排坑经验,适合有一定爬虫基础的读者进阶学习。目录前言一、小红书反爬机制概览二、环境准备2.1 Python环境2.2 浏览器驱动。

2201_76125261的博客 768

Android 开发入门实践(十三):用 Intent、UiState 和 Reducer 理解 MVI 的状态更新

本文记录第141—145课对MVI架构的入门实践,通过“返回列表”功能逐步构建意图(NewsIntent)、状态(NewsUiState)与状态转换(reduce)机制。基于单向数据流,用户操作生成意图,ViewModel通过Reducer根据旧状态计算新状态,并通过StateFlow更新Compose界面。代码实现清晰分离关注点,强化了对状态管理、事件驱动与数据流的理解。

Easyhood的博客 332

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

Android Message源码阅读

本文梳理了Android Handler机制中Message的核心设计:链表结构、消息复用池(sPool)及回收机制,重点解析了异步消息与同步屏障(SyncBarrier)的协同机制。当主线程需优先处理UI绘制等高优先级任务时,系统通过postSyncBarrier插入屏障,使Looper跳过普通同步消息,优先执行标记为异步的UI渲染任务,确保帧率流畅。该机制是保障Android界面响应性的关键技术之一。

u012116089的博客 201

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

Android Laya 与 Native Bridge:页面识别、双向通信、协议设计和崩溃定位

Laya 与 Native 通信的难点不在于某个或的写法,而在于边界:页面来源是否可信、协议是否明确、线程是否正确、请求是否幂等、页面是否仍然存在、日志是否能关联一次完整请求。建立这些边界后,才能把“页面白屏”“按钮无响应”“重复消息”和“Native 崩溃”拆成可验证的层次,并沿着真实调用链找到根因。

路在脚下,幸福在手中,莫贪!!!!! 160

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

安卓部署Linux性能实测:一颗移动处理器,能否胜任日常 Linux 开发?

本文通过在一加Ace5上部署NimoteCode的ARM64 Linux环境,测试了其在CoreMark、SQLite编译及并行构建中的表现。结果显示,尽管单核性能约2.34GHz,多核扩展比达6.15×,但优化编译耗时仍高达35秒,反映移动处理器虽具备一定开发能力,却受限于文件系统开销与运行环境(如PRoot)。实际开发中,非优化构建效率较高,而并行编译可显著提速。结论:安卓手机可作为轻量级开发辅助工具,但无法替代桌面环境,真正价值在于便携性与即时响应,而非全功能替代。

一个不知名码农的专栏 325

BUUCTF-菜刀流量-MISC-学习笔记

从 1970-01-01 00:00:00 UTC 起算的秒数,——Wireshark 直接告诉你它回答的是谁;由表可知道,96帧返回了flag.rar。, 代表删除键,先删了4次,又删了1次。所以密码是:SuperMaster。解析128帧的响应,即133帧。所以这是一个标准抓包文件,用。解压压缩包拿到html代码。:选中 128 帧,展开。:128 和 131 的。能把一问一答放在一起看;是八进制(Oct)的数字。(或 TCP 层)看到。对比一下ASCii 码表。

晓梦林的博客 67

云手机私有化部署完整方案:基于ARM服务器搭建私有安卓云集群

ARM 服务器是私有化安卓云集群最优硬件底座,原生架构匹配 Android,高密度、低损耗,非常适合企业内网场景。整套私有化方案的核心,从来不是 “跑起来安卓”,而是隔离可控、可审计、可运维、可扩容。两条路线各有取舍:开源自建灵活、门槛高;商用私有化交付开箱即用、安全能力完备,是当前企业生产环境主流方案。六边云手机私有化方案,补齐了自建方案在驱动适配、管控平台、审计合规、信创适配上的短板,适合对数据主权、内网隔离有强需求的政企、自研 App、垂直行业客户。

a598652的博客 343

Android 17 全栈性能分析关键字与源码手册

FrameTimeline 找异常帧,ATrace 找阶段,thread_state 找等待类型,ftrace 找内核原因,Simpleperf 找 CPU 热点,驱动源码找最终触发条件;任何根因结论都必须回到同一对象、同一时间窗口和同一条依赖链。

weixin_43228946的博客 375

CTF 命令执行题学习笔记:终端特殊字符 $IFS 与 %09 的用法(HelloCTF RCE-labs)

空格被过滤时:用%09(TAB)或$IFS代替空格关键词被过滤时:用通配符?或字符类[f]拼出被禁的词,让 WAF 在原始字符串里看不到它,shell 在执行时再展开这类技巧在后续的命令执行题里会反复用到,建议亲手在靶机上敲一遍感受一下。

YY888888_的博客 543

Android 开发入门实践(九):把新闻数据与页面状态交给 ViewModel

本文记录第110—117课学习成果:将页面标题、新闻列表及选中编号逐步迁移至NewsViewModel,通过ViewModelProvider获取实例并读取数据。页面调用ViewModel方法处理选择与返回,实现状态管理解耦。过程中纠正了对Activity重建机制的误解,并厘清mutableStateOf的可观察性与ViewModel对象生命周期的区别,深化了对Compose状态更新机制的理解。

Easyhood的博客 222

谷歌相机9.2下载(GCam 安卓通用版 安装与使用说明)

谷歌相机9.2版移植自Pixel原生相机,支持Camera2 API的Android 10+设备安装,凭借多帧合成技术在夜景、HDR+与人像模式表现优异。可提升暗光画质、优化动态范围与背景虚化效果,支持视频防抖及配置文件自定义。安装需确认机型兼容性,建议备份原相机,避免冲突。资源可通过kuake链接获取,仅限学习测试使用。

2611_96675819的博客 174
上一篇: Android Lesson One: Getting Started
下一篇: Android Lesson Three: Moving to Per-Fragment Lighting
incanus
博客等级 码龄15年 15粉丝 12原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值